pyspark-agg 中计数函数的奇怪行为

pyspark-strange behavior of count function inside agg

我正在使用 spark 2.4.0 我在使用计数函数进行聚合时观察到一个奇怪的行为。

from pyspark.sql import functions as F
tst=sqlContext.createDataFrame([(1,2),(1,5),(2,None),(2,3),(3,None),(3,None)],schema=['col1','col2'])
tst.show()
+----+----+
|col1|col2|
+----+----+
|   1|   2|
|   1|   5|
|   2|null|
|   2|   3|
|   3|null|
|   3|null|
+----+----+

tst.groupby('col1').agg(F.count('col2')).show()
+----+-----------+
|col1|count(col2)|
+----+-----------+
|   1|          2|
|   3|          0|
|   2|          1|
+----+-----------+

这里可以看到没有计算空值。我搜索了文档,但没有提到函数计数不计算空值的地方。 更让我惊讶的是这个

tst.groupby('col1').agg(F.count(F.col('col2').isNull())).show()
+----+---------------------+
|col1|count((col2 IS NULL))|
+----+---------------------+
|   1|                    2|
|   3|                    2|
|   2|                    2|
+----+---------------------+

这里我完全糊涂了。当我使用 isNull() 时,它不应该只计算空值吗?为什么要计算所有值?

我遗漏了什么吗?

在这两种情况下,您看到的结果都是预期的结果。

关于第一个示例:检查 Scala source of count count(*)count('col2') 之间存在细微差别:

FUNC(*) - Returns the total number of retrieved rows, including rows containing null.
FUNC(expr[, expr...]) - Returns the number of rows for which the supplied expression(s) are all non-null.

这解释了为什么 null 个条目没有被计算在内。

如果您将代码更改为

tst.groupby('col1').agg(F.count('*')).show()

你得到

+----+--------+
|col1|count(1)|
+----+--------+
|   1|       2|
|   3|       2|
|   2|       2|
+----+--------+

关于第二部分:表达式F.col('col2').isNull() returns 一个布尔值。无论此布尔值的实际值是多少,都会计算该行,因此您会看到 2.