PySpark中如何正确表示并过滤DataFrame的空列表列值
Spark DataFrame空列表列值筛选实现方案
报错根因
你写的df.filter(df.ingredients == [])之所以运行失败,是因为等号右侧的[]是Python原生列表对象,Spark运行时无法将这类Java/Python侧的原生集合自动转换为Spark内部ArrayType对应的合法字面量,因此抛出java.lang.RuntimeException: Unsupported literal type class java.util.ArrayList []的运行时错误。
正确实现方式
方式1:用size()函数判断数组长度(全版本兼容,优先推荐)
借助Spark内置的数组长度计算函数size(),判断目标列的元素个数为0即可精准匹配空列表的行。这个写法不依赖原生Python列表的比较逻辑,Spark 2.x、3.x全版本都能稳定运行。
from pyspark.sql.functions import size # 筛选Ingredients列值为空列表的行 result_df = df.filter(size(df.Ingredients) == 0) display(result_df)
注意: size()对值为null的数组列会返回-1,不会把null值误判为空列表,完全匹配你仅筛选空列表的场景。如果需要同时把null值也纳入筛选范围,可以叠加判断条件:
from pyspark.sql.functions import size, col result_df = df.filter((size(col("Ingredients")) == 0) | (col("Ingredients").isNull()))
方式2:用Spark内置函数构造空数组做等值比较(Spark 3.0+支持)
如果需要走等值匹配逻辑,可以通过Spark内置的array()函数不传入参数,直接构造Spark内部的空数组对象作为比较值,避免传入Python原生列表触发类型错误:
from pyspark.sql.functions import array result_df = df.filter(df.Ingredients == array()) display(result_df)
这个写法的筛选结果和size()==0的逻辑完全一致,只会匹配值为真·空列表的行,不会匹配null值。
内容的提问来源于stack exchange,提问作者bakun
相关产品推荐
相关产品推荐

