apache-spark - 如何计算火花组的百分比?
问题描述
我有以下形式的数据:
FUND|BROKER|QTY
F1|B1|10
F1|B1|50
F1|B2|20
F1|B3|20
当我按 FUND 和 BROKER 分组时,我想将 QTY 计算为组级别总数的百分比。像这样,
FUND|BROKER|QTY %|QTY EXPLANATION
F1|B1|60%|(10+50)/(10+50+20+20)
F1|B2|20%|(20)/(10+50+20+20)
F1|B2|20%|(20)/(10+50+20+20)
或者当我只按基金分组时,就像这样
FUND|BROKER|QTY %|QTY EXPLANATION
F1|B1|16.66|(10)/(10 + 50)
F1|B1|83.33|(50)/(10 + 50)
F1|B2|100|(20)/(20)
F1|B3|100|(20)/(20)
如果可能的话,我想使用 spark-sql 或通过数据框函数来实现这一点。
我想我必须使用 Windowing 函数,这样我才能访问分组数据集的总数,但我没有太多运气以正确的方式使用它们。
Dataset<Row> result = sparkSession.sql("SELECT fund_short_name, broker_short_name,first(quantity)/ sum(quantity) as new_col FROM margin_summary group by fund_short_name, broker_short_name" );
解决方案
PySpark SQL 解决方案。
这可以使用sum
定义 2 个窗口的窗口函数来完成 - 一个在经纪人、基金上分组,另一个仅在基金上分组。
from pyspark.sql import Window
from pyspark.sql.functions import sum
w1 = Window.partitionBy(df.fund,df.broker)
w2 = Window.partitionBy(df.fund)
res = df.withColumn('qty_pct',sum(df.qty).over(w1)/sum(df.qty).over(w2))
res.select(res.fund,res.broker,res.qty_pct).distinct().show()
编辑:结果 2 更简单。
res2 = df.withColumn('qty_pct',df.qty/sum(df.qty).over(w1))
res2.show()
SQL解决方案将是
select distinct fund,broker,100*sum(qty) over(partition by fund,broker)/sum(qty) over(partition by fund)
from tbl
推荐阅读
- python - 整数列表上的 CountVectorizer
- javascript - 如何在 Meteor 的后端读取文件?
- java - 线程“主”org.lwjgl.opengl.OpenGLException 中的异常:操作无效 (1282)
- ios - 推送新的 UIViewController 时 UISearchController 消失
- sitecore - SitecoreJSS 9.1 发布日期和 SitecoreJSS 9 限制
- r - ggraph - 根据频率增加节点大小
- javascript - NodeJS - 使用返回的 Promise 更新对象
- java - Android Studio:是否可以同时运行两个活动?
- gitlab - 更改 gitlab 运行器的克隆目录
- package - 在主函数(Scala)中无法检测到创建的单例对象