Spark DataFrame分组聚合:total统计正确但delayed统计异常原因
问题原因与解决方案
为什么count($"col_2" === 1)统计结果异常?
这是因为Spark中count()函数的特性:它会统计所有非Null的值,不管这个值是true还是false。当你写$"col_2" === 1时,这个表达式会返回一个布尔类型的列,每一行的结果要么是true要么是false——这两个值都不属于Null,所以count()会把所有行都算进去,最终delayed的结果会和total完全一致,这就是你看到的异常情况。
正确的实现方式
这里有两种常用的正确做法,都能准确统计col_2等于1的行数:
方法1:使用sum()将布尔值转成数值统计
布尔值在Spark中可以自动隐式转换为整数(true对应1,false对应0),所以直接对布尔表达式求和就能得到符合条件的行数:
df.groupBy($"col_1") .agg( sum(($"col_2" === 1).cast("int")).as("delayed"), // 显式转int更稳妥 count(lit(1)).as("total") ).show(100)
或者依赖隐式转换的简洁写法:
df.groupBy($"col_1") .agg( sum($"col_2" === 1).as("delayed"), count(lit(1)).as("total") ).show(100)
方法2:使用countWhen()函数(Spark 2.0+支持)
Spark提供了专门的countWhen()函数,它会直接统计满足指定条件的行数,代码可读性更高:
import org.apache.spark.sql.functions.countWhen df.groupBy($"col_1") .agg( countWhen($"col_2" === 1).as("delayed"), count(lit(1)).as("total") ).show(100)
这两种方法都能得到你预期的结果:
| col_1 | delayed | total |
|---|---|---|
| aaa | 1 | 2 |
| bbb | 3 | 3 |
内容的提问来源于stack exchange,提问作者user9544698
相关产品推荐
相关产品推荐

