我有一个这样的数据集,
test = spark.createDataFrame([
(0, 1, 5, "2018-06-03", "Region A"),
(1, 1, 2, "2018-06-04", "Region B"),
(2, 2, 1, "2018-06-03", "Region B"),
(4, 1, 1, "2018-06-05", "Region C"),
(5, 3, 2, "2018-06-03", "Region D"),
(6, 1, 2, "2018-06-03", "Region A"),
(7, 4, 4, "2018-06-03", "Region A"),
(8, 4, 4, "2018-06-03", "Region B"),
(9, 5, 4, "2018-06-03", "Region A"),
(10, 5, 4, "2018-06-03", "Region B"),
])\
.toDF("orderid", "customerid", "price", "transactiondate", "location")
test.show()
Run Code Online (Sandbox Code Playgroud)
我可以像这样汇总每个客户在每个区域的订单:
temp_result = test.groupBy("customerid").pivot("location").agg(count("orderid")).na.fill(0)
temp_result.show()
Run Code Online (Sandbox Code Playgroud)
现在,我想通过确定值是否存在(即 0 或 1)来简单地聚合数据,而不是 or ,如下sum所示count
我可以通过以下方式获得上述结果
for field in temp_result.schema.fields:
if str(field.name) not in ['customerid', "overall_count", "overall_amount"]:
name = str(field.name)
temp_result = temp_result.withColumn(name, \
when(col(name) >= 1, 1).otherwise(0))
Run Code Online (Sandbox Code Playgroud)
但有没有更简单的方法来获取它?
您基本上已经完成了 - 只需进行一点调整即可获得您想要的结果。在聚合中,添加计数比较并将布尔值转换为整数(如果有必要):
temp_result = test.groupBy("customerid")\
.pivot("location")\
.agg((count("orderid")>0).cast("integer"))\
.na.fill(0)
temp_result.show()
Run Code Online (Sandbox Code Playgroud)
结果为:
+----------+--------+--------+--------+--------+
|customerid|Region A|Region B|Region C|Region D|
+----------+--------+--------+--------+--------+
| 5| 1| 1| 0| 0|
| 1| 1| 1| 1| 0|
| 3| 0| 0| 0| 1|
| 2| 0| 1| 0| 0|
| 4| 1| 1| 0| 0|
+----------+--------+--------+--------+--------+
Run Code Online (Sandbox Code Playgroud)
如果出现 Spark 错误,您可以使用此解决方案,它通过附加步骤进行计数比较:
temp_result = test.groupBy("customerId", "location")\
.agg(count("orderid").alias("count"))\
.withColumn("count", (col("count")>0).cast("integer"))\
.groupby("customerId")\
.pivot("location")\
.agg(sum("count")).na.fill(0)
temp_result.show()
Run Code Online (Sandbox Code Playgroud)