PySpark DataFrame的cube方法返回重复空值问题排查
解决PySpark DataFrame cube方法返回重复空值的问题
我之前也碰到过这个困惑,其实这并不是bug,而是cube方法的预期行为——它会生成所有维度组合的聚合结果,包括单个维度的所有分组值,以及代表"总计"的空值行,而原数据中本身存在的null值会被当作一个独立分组,所以就出现了看起来重复的null行。
先补全可复现的完整测试代码
from pyspark.sql import SparkSession from pyspark.sql import Row from pyspark.sql.functions import count, grouping, when # 初始化SparkSession spark = SparkSession.builder.appName("CubeNullIssue").getOrCreate() # 完整测试数据集(补全你截断的部分) l = [ Row(value=True), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=True), Row(value=True), Row(value=None), Row(value=True), Row(value=None), Row(value=True) ] df = spark.createDataFrame(l)
先看问题现象
当我们执行cube聚合时:
df.cube("value").agg(count("*").alias("count")).show()
输出会出现两个null行:
+-----+-----+ |value|count| +-----+-----+ | true| 16| | null| 8| | null| 24| +-----+-----+
这两个null的含义完全不同:
- 第一个
null:原数据中value字段本身为null的分组计数(共8条) - 第二个
null:cube自动生成的总计行(所有行的总数:16+8=24)
解决方案:区分两种空值
我们可以用PySpark内置的grouping函数来标记这两种null的身份:
grouping("value")返回0:表示这是基于实际字段值的分组(包括原数据的null)grouping("value")返回1:表示这是cube生成的总计行
1. 明确标记两种空值
df.cube("value")\ .agg( count("*").alias("count"), grouping("value").alias("is_total") )\ .show()
输出:
+-----+-----+--------+ |value|count|is_total| +-----+-----+--------+ | true| 16| 0| | null| 8| 0| | null| 24| 1| +-----+-----+--------+
2. 给总计行替换明确标识
如果需要保留总计行但不想用null混淆,可以给它赋值一个清晰的标签:
df.cube("value")\ .agg(count("*").alias("count"))\ .withColumn("value", when(grouping("value") == 1, "Total").otherwise(df.value))\ .show()
输出:
+-----+-----+ |value|count| +-----+-----+ | true| 16| | null| 8| |Total| 24| +-----+-----+
3. 直接过滤掉总计行
如果业务不需要总计结果,直接过滤即可:
df.cube("value")\ .agg(count("*").alias("count"))\ .filter(grouping("value") == 0)\ .show()
输出:
+-----+-----+ |value|count| +-----+-----+ | true| 16| | null| 8| +-----+-----+
内容的提问来源于stack exchange,提问作者Jas
相关产品推荐
相关产品推荐

