在 PySpark 中对不同值求和并创建总和百分比的有效方法
Efficient way to sum over distinct values and create percentage over sums in PySpark
假设 I 有这样的数据框:
df
Day Group Counts
Monday 0 7
Monday 0 45
Monday 1 70
Tuesday 1 18
Tuesday 1 13
Tuesday 0 84
如何创建一个名为 'percentages' 的新列,其中包含按组和日期给出的百分比?
expected df
Day Group Counts Percentage
Monday 0 7 7/52
Monday 0 45 7/45
Monday 1 70 70/70
Tuesday 1 18 18/31
Tuesday 1 13 13/31
Tuesday 0 84 84/84
我正在做类似的事情:
groupby('day', 'group').agg((F.count('Counts') / F.sumDistinct('Counts'))
但是我遇到了错误。
我应该使用 Window 功能吗?
您的方法通常应该有效。您只需要为聚合提供一个别名并将表达式放在括号中。
df_agg = df.groupby('day', 'group').agg((F.count('Counts') / F.sumDistinct('Counts')).alias('Percentage'))
df = df.join(df_agg, join=['day', 'group'], 'left')
是的你可以使用Window函数,计算每天和组的元素,然后进行除法:
from pyspark.sql import Window
window = Window.partitionBy('Day','Group')
df = df\
.withColumn('count_per_window', sum('Counts').over(window))\
.withColumn('Percentage', col('Counts')/col('count_per_window'))\
.drop('count_per_window')
假设 I 有这样的数据框:
df
Day Group Counts
Monday 0 7
Monday 0 45
Monday 1 70
Tuesday 1 18
Tuesday 1 13
Tuesday 0 84
如何创建一个名为 'percentages' 的新列,其中包含按组和日期给出的百分比?
expected df
Day Group Counts Percentage
Monday 0 7 7/52
Monday 0 45 7/45
Monday 1 70 70/70
Tuesday 1 18 18/31
Tuesday 1 13 13/31
Tuesday 0 84 84/84
我正在做类似的事情:
groupby('day', 'group').agg((F.count('Counts') / F.sumDistinct('Counts'))
但是我遇到了错误。
我应该使用 Window 功能吗?
您的方法通常应该有效。您只需要为聚合提供一个别名并将表达式放在括号中。
df_agg = df.groupby('day', 'group').agg((F.count('Counts') / F.sumDistinct('Counts')).alias('Percentage'))
df = df.join(df_agg, join=['day', 'group'], 'left')
是的你可以使用Window函数,计算每天和组的元素,然后进行除法:
from pyspark.sql import Window
window = Window.partitionBy('Day','Group')
df = df\
.withColumn('count_per_window', sum('Counts').over(window))\
.withColumn('Percentage', col('Counts')/col('count_per_window'))\
.drop('count_per_window')