我有两个pyspark数据帧
例如,我有一个如下的用户表
users col1 col2 col3
1 A AA AAA
1 A AA AAA
2 A AB AAB
3 A AA AAA
4 A AA AAA
6 B BB BBB
7 B BB BBB
8 A AA AAA
和下面的费用表数据框
col1 col2 col3 cost
A AA AAA 1000
A AB AAB 200
B BB BBB 420
我需要将此费用平均分配给各个用户。像下面一样,我需要像下面这样的最终输出列
结果列
users col1 col2 col3 cost
1 A AA AAA 200
1 A AA AAA 200
2 A AB AAB 200
3 A AA AAA 250
4 A AA AAA 200
6 B BB BBB 210
7 B BB BBB 210
8 A AA AAA 200
我该如何使用pysaprk数据框:这是示例数据集。我的用户列大小约为1GB,成本表约为10 Mb。我是pyspark的新手,什么是解决此问题的最佳方法?
更新:需要更新示例数据帧的行数
答案 0 :(得分:0)
这是适合您的解决方案
from pyspark.sql.functions import count, broadcast, col
user.join(broadcast(user.groupBy("col1", "col2", "col3")\
.agg(count("users").alias("count"))\
.join(broadcast(cost), ["col1", "col2", "col3"])\
.withColumn('cost', col('cost')/col('count'))), ["col1", "col2", "col3"])\
.drop('count')\
.show(truncate=False)
应该给您
+----+----+----+-----+-----+
|col1|col2|col3|users|cost |
+----+----+----+-----+-----+
|A |AA |AAA |1 |250.0|
|A |AB |AAB |2 |200.0|
|A |AA |AAA |3 |250.0|
|A |AA |AAA |4 |250.0|
|B |BB |BBB |6 |210.0|
|B |BB |BBB |7 |210.0|
|A |AA |AAA |8 |250.0|
+----+----+----+-----+-----+
说明:
上述解决方案分为三部分
第一部分是汇总
user.groupBy("col1", "col2", "col3")\
.agg(count("users").alias("count"))
为您提供
+----+----+----+-----+
|col1|col2|col3|count|
+----+----+----+-----+
|A |AB |AAB |1 |
|B |BB |BBB |2 |
|A |AA |AAA |4 |
+----+----+----+-----+
第二个是第一次连接(我使用broadcast
函数,正如您所说的 cost数据帧很小)
user.groupBy("col1", "col2", "col3") \
.agg(count("users").alias("count")) \
.join(broadcast(cost), ["col1", "col2", "col3"]) \
.withColumn('cost', col('cost')/col('count'))
应该给您
+----+----+----+-----+-----+
|col1|col2|col3|count|cost |
+----+----+----+-----+-----+
|A |AB |AAB |1 |200.0|
|B |BB |BBB |2 |210.0|
|A |AA |AAA |4 |250.0|
+----+----+----+-----+-----+
最后是上述输出与用户数据框的连接。然后删除多余的计数列
我希望答案会有所帮助