Spark使用FILTER过滤RDD后调用head方法报错问题排查
问题根因
你的报错是变量赋值错误导致的:
- DataFrame的
show()方法作用是打印数据到控制台,返回值为None,你把这个None值赋给了df1,后续执行df1.head(5)相当于对None类型对象调用方法,必然触发类型报错。 - 另外你当前的写法还有性能隐患:
collect()会把O列的全量数据拉取到Driver节点内存生成Python列表,当数据集规模较大时,很容易触发Driver端内存溢出,不适合生产环境大表场景。
修复方法
小数据量场景(沿用原有逻辑)
只需要把赋值和show()调用拆分即可,不要把show()的返回值赋值给变量:
list_O = df.select('O').rdd.flatMap(lambda x: x).collect() # 先赋值过滤后的DataFrame df1 = df.filter(df.D.isin(list_O)) # 单独调用show打印结果,不要接赋值 df1.show() # 此时调用head可正常返回结果 df1.head(5)
大数据量场景(推荐写法)
用左半连接实现过滤逻辑,不需要把全量O列数据拉到Driver,计算全部在集群节点执行,性能和稳定性更好:
# 提取O列所有节点并去重 o_node_df = df.select("O").distinct() # left_semi join会保留左表中能在右表匹配上关联键的记录,正好匹配过滤需求 df1 = df.join(o_node_df, df.D == o_node_df.O, "left_semi") # 验证结果 df1.show() df1.head(5)
用提供的示例数据运行上述代码,会自动过滤掉t不在O列的c-t行,最终保留3条有效边记录:
| O | D |
|---|---|
| a | b |
| b | g |
| g | a |
内容的提问来源于stack exchange,提问作者roger montez
相关产品推荐
相关产品推荐

