PySpark如何无需join直接替换DataFrame指定列的映射值
PySpark 列值映射替换的无冗余步骤实现
针对性别枚举值替换的需求,完全不需要按join后删列、重命名的繁琐流程实现,可根据映射表的数据规模选择对应方案:
小维度映射场景(推荐,无join开销)
如果df2这类枚举映射表数据量极小,可以直接把映射关系提取为字典,调用DataFrame原生的replace方法直接更新原列值,全程不需要join操作,也不要求两表关联列名必须一致:
# 从映射表提取key-value对应关系 gender_map = {row.gender: row.enum for row in df2.collect()} # 直接对目标列做值替换,原列值会被直接更新为映射后的枚举值 new_df = df1.replace(to_replace=gender_map, subset=['gender'])
执行后直接得到目标结果,不需要额外列处理:
+-----+------+ | name|gender| +-----+------+ | Andy| 1| |Julie| 2| |Danny| 1| +-----+------+
该方案没有join带来的shuffle开销,性能最优,代码最简洁,适合固定枚举、小维度映射的场景。
大维度映射场景(join一步完成处理)
如果映射表数据量较大,不适合拉取到驱动端,可以在join阶段直接通过select完成列筛选和重命名,省去join后的冗余操作,同时支持两侧关联列名不同的场景:
from pyspark.sql.functions import col new_df = df1.join( df2, # 关联条件可自由指定,不需要两表关联列名完全相同 on=df1.gender == df2.gender, how='inner' ).select( # 保留原表除待替换列外的所有字段 *[col(c) for c in df1.columns if c != 'gender'], # 直接将映射得到的枚举值列重命名为原列名,一步到位 col('enum').alias('gender') )
该方案和常规join的执行性能完全一致,不需要先join再单独执行drop、重命名列的操作,也不需要提前对两个表的关联列做重命名对齐。
内容的提问来源于stack exchange,提问作者Tristan Tran
相关产品推荐
相关产品推荐

