在 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')