PySpark join后如何编程式按列表批量删除指定多列
PySpark Join后通过预定义列表批量删列的实现方法
问题原因
原代码失效是因为columnToDelete列表存储的是Join操作前两个独立DataFrame的Column对象引用,Join生成的新DataFrame有独立的列元数据体系,绑定旧DataFrame的Column对象无法和新表的列做匹配,导致drop方法识别不到目标列。
正确实现方案
方案1:直接存储列名字符串(最稳定,官方推荐)
直接把待删除的列名以字符串形式存入列表,不绑定任何旧DataFrame的Column对象,Join后直接传入drop方法即可:
# 待删除列直接定义为字符串格式的列名 columnToDelete = ["name", "gender"] listjoin = empDFTems.join( empDFTems2, on = empDFTems["emp_id"] == empDFTems2["emp_id"], how = "left" ).drop(*columnToDelete)
方案2:从已有Column对象提取纯列名
如果场景里必须保留原来引用Column对象的写法,可以在Join前先把Column对象对应的纯列名提取出来,脱离旧DataFrame的绑定再传入drop:
from pyspark.sql import Column # 定义原始的Column引用列表 raw_columns_to_delete = [empDFTems2.name, empDFTems.gender] # 提取纯列名,自动去掉旧DF的绑定前缀 columnToDelete = [ col._jc.toString().split(".")[-1] for col in raw_columns_to_delete if isinstance(col, Column) ] listjoin = empDFTems.join( empDFTems2, on = empDFTems["emp_id"] == empDFTems2["emp_id"], how = "left" ).drop(*columnToDelete)
注意事项
- 如果两个待Join的DataFrame存在同名列,直接传入列名会把所有同名的列全部删除。如果需要精准删除某一侧的列,建议在Join前先给对应列加前缀重命名做区分,不要依赖旧DataFrame的Column引用做删除
- PySpark的
drop方法对跨DataFrame的Column对象引用兼容性很差,传入字符串列名是兼容性最高的写法
内容的提问来源于stack exchange,提问作者D556
相关产品推荐
相关产品推荐

