“任何值”的 PySpark 聚合函数

Dim*_*old 4 python coalesce apache-spark apache-spark-sql pyspark

我有一个带有A字段的 PySpark 数据框,几个B依赖于A( A->B) 的C字段和我想按每个 A 聚合的字段。例如:

A | B | C
----------
A | 1 | 6
A | 1 | 7
B | 2 | 8
B | 2 | 4
Run Code Online (Sandbox Code Playgroud)

我希望按 分组A,呈现任何一个B并在 上运行聚合(比方说SUMC

预期的结果是:

A | B | C
----------
A | 1 | 13
B | 2 | 12
Run Code Online (Sandbox Code Playgroud)

SQL明智我会这样做:

SELECT A, COALESCE(B) as B, SUM(C) as C
FROM T
GROUP BY A
Run Code Online (Sandbox Code Playgroud)

PySpark 的方法是什么?

我可以按 A 和 B 分组或MIN(B)按每个 A 进行选择,例如:

df.groupBy('A').agg(F.min('B').alias('B'),F.sum('C').alias('C'))
Run Code Online (Sandbox Code Playgroud)

或者

df.groupBy(['A','B']).agg(F.sum('C').alias('C'))
Run Code Online (Sandbox Code Playgroud)

但这似乎效率低下。coalescePySpark 中是否有类似于 SQL的东西?

谢谢

eli*_*sah 9

你只需要使用first

from pyspark.sql.functions import first, sum, col
from pyspark.sql import Row

array = [Row(A="A", B=1, C=6),
         Row(A="A", B=1, C=7),
         Row(A="B", B=2, C=8),
         Row(A="B", B=2, C=4)]
df = sqlContext.createDataFrame(sc.parallelize(array))

results = df.groupBy(col("A")).agg(first(col("B")).alias("B"), sum(col("C")).alias("C"))
Run Code Online (Sandbox Code Playgroud)

现在让我们检查结果:

results.show()
# +---+---+---+
# |  A|  B|  C|
# +---+---+---+
# |  B|  2| 12|
# |  A|  1| 13|
# +---+---+---+
Run Code Online (Sandbox Code Playgroud)

来自评论:

first这里是计算相当于any

groupBy导致洗牌。因此,非确定性行为是预期的。

这在以下文件中得到证实first

聚合函数:返回组中的第一个值。默认情况下,该函数返回它看到的第一个值。当 ignoreNulls 设置为 true 时,它​​将返回它看到的第一个非空值。如果所有值都为 null,则返回 null。注意:: 该函数是不确定的,因为它的结果取决于行的顺序,这在 shuffle 之后可能是不确定的。

所以是的,在计算上是相同的,如果您需要确定性行为,这就是您需要使用排序的原因之一。

我希望这有帮助 !