PySpark DataFrame中空数组size为何为1?(版本2.3.2)
问题:PySpark中空数组的size为何返回1?
你在PySpark 2.3.2中遇到的问题本质是视觉展示的误导,以下是具体分析和验证:
测试代码
import pyspark.sql.functions as F import pyspark.sql.types as T new_customers = spark.createDataFrame( data=[["Karen", ["a"]], ["Penny", ["b"]], ["John", [None]], ["Cosimo", ["d"]]], schema=["name", "val"] ) new_customers.printSchema() new_customers.show(5, False) new_customers = new_customers.withColumn("new_val", F.size("val")) new_customers.show(10, truncate=False)
运行结果
root |-- name: string (nullable = true) |-- val: array (nullable = true) | |-- element: string (containsNull = true) +------+---+ |name |val| +------+---+ |Karen |[a]| |Penny |[b]| |John |[] | |Cosimo|[d]| +------+---+ +------+---+-------+ |name |val|new_val| +------+---+-------+ |Karen |[a]|1 | |Penny |[b]|1 | |John |[] |1 | <- # 为何此处为1? |Cosimo|[d]|1 | +------+---+-------+
原因分析
- 数组并非空数组:你给John赋值的
[None]是包含一个null元素的数组,而非空数组[]。 - 展示的视觉简化:PySpark在
show()输出时,会把包含单个null元素的数组简化显示为[],但这只是展示层面的处理,数组实际长度仍是1。 size函数的逻辑:F.size()统计的是数组中元素的总个数,不管元素是否为null,所以包含一个null的数组会返回1。
验证方法
可以通过以下代码验证数组中确实存在null元素:
# 检查数组是否包含null new_customers.withColumn("has_null", F.array_contains("val", None)).show(truncate=False) # 展开数组查看元素 new_customers.select("name", F.explode("val").alias("element")).show(truncate=False)
运行后会看到John的行has_null为true,展开后会显示一个null元素,证明数组长度确实是1。
处理方案(如果需要将含单个null的数组视为空数组)
如果需要把这种包含单个null的数组当作空数组处理,可以过滤掉数组中的null元素后再计算长度,或者直接替换为空数组:
# 过滤数组中的null元素,再计算长度 new_customers = new_customers.withColumn( "clean_val", F.filter("val", lambda x: x.isNotNull()) ).withColumn("clean_size", F.size("clean_val")) # 或者直接将[null]替换为空数组 new_customers = new_customers.withColumn( "fixed_val", F.when(F.array_contains("val", None) & (F.size("val") == 1), F.array()).otherwise("val") ).withColumn("fixed_size", F.size("fixed_val")) new_customers.show(truncate=False)
内容的提问来源于stack exchange,提问作者user3448011
相关产品推荐
相关产品推荐

