“任何值”的 PySpark 聚合函数

问题描述 投票:0回答:2

我有一个带有

A
字段的 PySpark Dataframe,几个依赖于
B
(
A
) 和我想要为每个 A 聚合的
A->B
字段的
C
字段。例如:

A | B | C
----------
A | 1 | 6
A | 1 | 7
B | 2 | 8
B | 2 | 4

我希望按

A
进行分组,呈现任何
B
并在
SUM
上运行聚合(假设是
C
)。

预期结果是:

A | B | C
----------
A | 1 | 13
B | 2 | 12

就 SQL 而言,我会这样做:

SELECT A, COALESCE(B) as B, SUM(C) as C
FROM T
GROUP BY A

PySpark 的方法是什么?

我可以将 A 和 B 分组在一起,或者为每个 A 选择

MIN(B)
,例如:

df.groupBy('A').agg(F.min('B').alias('B'),F.sum('C').alias('C'))

df.groupBy(['A','B']).agg(F.sum('C').alias('C'))

但这似乎效率低下。 PySpark 中有类似 SQL

coalesce
的东西吗?

谢谢

python apache-spark pyspark apache-spark-sql coalesce
2个回答
14
投票

您只需要使用

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"))

现在让我们检查结果:

results.show()
# +---+---+---+
# |  A|  B|  C|
# +---+---+---+
# |  B|  2| 12|
# |  A|  1| 13|
# +---+---+---+

来自评论:

这里的

first
在计算上等同于
any
吗?

groupBy
导致随机播放。因此,“非确定性”行为是可以预料的。 这在

first

的文档中得到证实:


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

所以
是的

,在计算上是相同的,如果您需要确定性行为,这就是您需要使用排序的原因之一。 我希望这有帮助!


0
投票

您可以使用聚合函数

any_value

来完成此操作。

通过这个新函数重用@eliasah的答案:

from pyspark.sql.functions import any_value, 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(any_value(col("B")).alias("B"), sum(col("C")).alias("C"))

© www.soinside.com 2019 - 2024. All rights reserved.