我正在尝试按pyspark
数据帧中的ID列进行分组,并根据另一列的值对一列求和。
为说明起见,请考虑以下虚拟数据帧:
+-----+-------+---------+
| ID| type| amount|
+-----+-------+---------+
| 1| a| 55|
| 2| b| 1455|
| 2| a| 20|
| 2| b| 100|
| 3| null| 230|
+-----+-------+---------+
我想要的输出是:
+-----+--------+----------+----------+
| ID| sales| sales_a| sales_b|
+-----+--------+----------+----------+
| 1| 55| 55| 0|
| 2| 1575| 20| 1555|
| 3| 230| 0| 0|
+-----+--------+----------+----------+
因此,基本上,sales
将是amount
的总和,而sales_a
和sales_b
是amount
的总和,而type
是分别为a
或b
。
对于sales
,我知道可以这样做:
from pyspark.sql import functions as F
df = df.groupBy("ID").agg(F.sum("amount").alias("sales"))
对于其他人,我猜F.when
会有用,但是我不确定该怎么做。
答案 0 :(得分:1)
from pyspark.sql import functions as F
df = df.groupBy("ID").agg(F.sum("amount").alias("sales"))
dfPivot = df.filter("type is not null").groupBy("ID").pivot("type").agg(F.sum("amount").alias("sales"))
res = df.join(dfPivot, df.id== dfPivot.id,how='left')
然后将null
替换为0
。
这是一个通用解决方案,无论type
列中的值如何,都可以使用。因此,如果在数据帧中添加了type
c,那么它将创建列_c
答案 1 :(得分:1)
您可以根据type的值在聚合之前创建两列。
df.withColumn("sales_a", F.when(col("type") == "a", col("amount"))) \
.withColumn("sales_b", F.when(col("type") == "b", col("amount"))) \
.groupBy("ID") \
.agg(F.sum("amount").alias("sales"),
F.sum("sales_a").alias("sales_a"),
F.sum("sales_b").alias("sales_b"))