【发布时间】:2018-08-08 18:52:19
【问题描述】:
我有一个像这样的 Spark DataFrame:
+-----+--------+-------+-------+-------+-------+-------+
| Type|Criteria|Value#1|Value#2|Value#3|Value#4|Value#5|
+-----+--------+-------+-------+-------+-------+-------+
| Cat| 1| 1| 2| 3| 4| 5|
| Dog| 2| 1| 2| 3| 4| 5|
|Mouse| 4| 1| 2| 3| 4| 5|
| Fox| 5| 1| 2| 3| 4| 5|
+-----+--------+-------+-------+-------+-------+-------+
你可以用下面的代码重现它:
data = [('Cat', 1, 1, 2, 3, 4, 5),
('Dog', 2, 1, 2, 3, 4, 5),
('Mouse', 4, 1, 2, 3, 4, 5),
('Fox', 5, 1, 2, 3, 4, 5)]
columns = ['Type', 'Criteria', 'Value#1', 'Value#2', 'Value#3', 'Value#4', 'Value#5']
df = spark.createDataFrame(data, schema=columns)
df.show()
我的任务是添加 Total 列,该列是所有 Value 列的总和,其中 # 不超过该行的 Criteria。
在这个例子中:
- 对于行
'Cat':条件是1,所以Total就是Value#1。 - 对于行
'Dog':条件是2,所以Total是Value#1和Value#2的总和。 - 对于行
'Fox':条件是5,所以Total是所有列的总和(Value#1到Value#5)。
结果应该是这样的:
+-----+--------+-------+-------+-------+-------+-------+-----+
| Type|Criteria|Value#1|Value#2|Value#3|Value#4|Value#5|Total|
+-----+--------+-------+-------+-------+-------+-------+-----+
| Cat| 1| 1| 2| 3| 4| 5| 1|
| Dog| 2| 1| 2| 3| 4| 5| 3|
|Mouse| 4| 1| 2| 3| 4| 5| 10|
| Fox| 5| 1| 2| 3| 4| 5| 15|
+-----+--------+-------+-------+-------+-------+-------+-----+
我可以使用 Python UDF 做到这一点,但是我的数据集很大,而且 Python UDF 由于序列化而速度很慢。我正在寻找纯 Spark 解决方案。
我正在使用 PySpark 和 Spark 2.1
【问题讨论】:
-
在没有
udf的情况下完成此操作的一种方法是将 Values 列转换为数组,然后使用posexplode分解数组,过滤分解值
标签: python apache-spark pyspark apache-spark-sql