Spark DataFrame如何保留原列并新增非空标记列?
解决Spark DataFrame批量新增非空标记列的问题
这里提供两种可靠的实现方式,既能保留所有原列,又能批量生成目标标记列:
方法一:使用select一次性构造所有列
这种方式效率更高,无需循环多次操作DataFrame:
from pyspark.sql.functions import col, when # 获取所有列名 all_cols = df.columns # 提取需要生成标记列的目标列(除前两列外) target_cols = all_cols[2:] # 构造选择列列表:包含所有原列 + 批量生成的标记列 select_cols = all_cols + [ when(col(c).isNotNull(), 1).otherwise(0).alias(f"{c}_N") for c in target_cols ] # 生成最终结果DataFrame result_df = df.select(select_cols)
方法二:正确使用withColumn循环
如果习惯用循环操作,注意每次循环要更新DataFrame变量,避免覆盖之前的操作:
from pyspark.sql.functions import col, when target_cols = df.columns[2:] # 初始化结果DataFrame为原表 result_df = df for col_name in target_cols: # 每次循环都在当前结果表基础上新增标记列,并更新结果表 result_df = result_df.withColumn( f"{col_name}_N", when(col(col_name).isNotNull(), 1).otherwise(0) )
你之前遇到的问题原因
- 使用
select丢失原列:因为只传入了生成的标记列,没有包含原表的所有列,只要把原列和新列一起传入select就能解决。 - 循环
withColumn仅保留最后一列:因为每次循环都直接在原始df上调用withColumn,没有把新增列后的结果存下来,相当于每次都是从零开始添加一列,最后自然只保留最后一次的操作结果。只要每次循环更新结果变量,就能累积所有新增列。
内容的提问来源于stack exchange,提问作者budding pro
相关产品推荐
相关产品推荐

