Python pyspark在查找组的第一个值时进行聚合

Python pyspark在查找组的第一个值时进行聚合,python,apache-spark,pyspark,apache-spark-sql,Python,Apache Spark,Pyspark,Apache Spark Sql,假设我有5 TB以下模式的数据,并且我正在使用Pyspark | id | date | Month | KPI_1 | ... | KPI_n 对于90%的KPI,我只需要知道汇总到(id,月)级别的总和/最小值/最大值。对于剩余的10%,我需要知道基于日期的第一个值 我的一个选择是使用窗口。例如,我能做什么 from pyspark.sql import Window import pyspark.sql.functions as F w = Window.partitionBy("id

假设我有5 TB以下模式的数据,并且我正在使用Pyspark

| id | date | Month | KPI_1 | ... | KPI_n
对于90%的KPI,我只需要知道汇总到(id,月)级别的总和/最小值/最大值。对于剩余的10%,我需要知道基于日期的第一个值

我的一个选择是使用
窗口
。例如,我能做什么

from pyspark.sql import Window
import pyspark.sql.functions as F

w = Window.partitionBy("id", "Month").orderBy(F.desc("date"))

# for the 90% kpi
agg_df = df.withColumn("kpi_1", F.sum("kpi_1").over(w))
agg_df = agg_df.withColumn("kpi_2", F.max("kpi_2").over(w))
agg_df = agg_df.withColumn("kpi_3", F.min("kpi_3").over(w))
...

# Select last row for each window to get last accumulated sum for 90% kpis and last value for 10% kpi (which is equivalent to first value if ranked ascending). 

# continue process agg_df with filters based on sum/max/min values of 90% KIPs. 

但我不知道如何选择每个窗口的最后一行。是否有人有任何建议,或者是否有更好的方法进行汇总

假设我们有这些数据

+---+----------+-------+-----+-----+
|id |日期|月份| kpi | 1 | kpi | 2|
+---+----------+-------+-----+-----+
|  1|2000-01-01|2000-01|    1|  100|
|  1|2000-01-02|2000-01|    2|  200|
|  1|2000-01-03|2000-01|    3|  300|
|  1|2000-01-04|2000-01|    4|  400|
|  1|2000-01-05|2000-01|    5|  500|
|  1|2000-02-01|2000-02|   10|   11|
|  1|2000-02-02|2000-02|   20|   21|
|  1|2000-02-03|2000-02|   30|   31|
|  1|2000-02-04|2000-02|   40|   41|
+---+----------+-------+-----+-----+
我们要计算
kpi_1
的最小值、最大值和总和,并得到每组
kpi_2
的最后一个值

通过按
id
month
对数据进行分组,可以获得最小值、最大值和总和:

df_avg=df\
.groupBy(“id”、“月份”)\
.agg(F.sum(“kpi_1”)、F.min(“kpi_1”)、F.max(“kpi_1”)、F.first(“kpi_2”))\
。选择(“id”、“月份”、“总和(kpi_1)”、“最小值(kpi_1)”、“最大值(kpi_1)”)
df_平均值显示()
印刷品

+---+-------+----------+----------+----------+
|id |月|和(kpi|1)|最小(kpi|1)|最大(kpi|1)|
+---+-------+----------+----------+----------+
|  1|2000-02|       100|        10|        40|
|  1|2000-01|        15|         1|         5|
+---+-------+----------+----------+----------+
获取每组的
kpi_2
的最后一个值比较困难。第一个想法可能是在降序数据帧上使用聚合函数。一个简单的测试给了我正确的结果,但不幸的是,文档中指出“函数是不确定的,因为它的结果取决于行的顺序,而行的顺序在洗牌后可能是不确定的”

获取
kpi_2
的最后一个值的更好方法是使用问题中所示的窗口。由于窗口功能将起作用:

w=Window.partitionBy(“id”、“Month”).orderBy(F.desc(“date”))
df_first=df.withColumn(“row_number”,F.row_number()。在(w)上方)。其中(“row_number=1”)\
.删除(“行号”)\
.选择(“id”、“月份”、“KPI_2”)
df_first.show()
印刷品

+---+-------+-----+
|id |月| KPI|2|
+---+-------+-----+
|  1|2000-02|   41|
|  1|2000-01|  500|
+---+-------+-----+
将两个零件连接在一起可获得所需的结果:

df_result=df_avg.join(df_first,['id','month'])
df_result.show()
印刷品

+---+-------+----------+----------+----------+-----+
|id |月|和(kpi|1)|最小(kpi|1)|最大(kpi|1)| kpi|2|
+---+-------+----------+----------+----------+-----+
|  1|2000-02|       100|        10|        40|   41|
|  1|2000-01|        15|         1|         5|  500|
+---+-------+----------+----------+----------+-----+