Spark中不使用CASE WHEN实现DataFrame列差异标记列生成
批量标记DataFrame中列对差异的解决方案
不用手动编写大量CASE WHEN语句,通过pandas的批量处理逻辑可以高效解决这个问题,以下是具体实现:
核心思路
- 统一管理需要对比的列对(如
(B,B_1)、(C,C_1)等) - 先校验
A与A_1的相等性作为基础条件 - 对符合条件的行,自动收集所有与对应
_1列不等的原始列名,用逗号拼接成标记值
代码实现(基础版)
import pandas as pd # 示例DataFrame df = pd.DataFrame({ 'A': [1, 2, 3], 'A_1': [1, 2, 4], 'B': [5, 6, 7], 'B_1': [6, 6, 8], 'C': [9, 10, 11], 'C_1': [10, 10, 12], 'D': [13, 14, 15], 'D_1': [14, 14, 16], 'E': [17, 18, 19], 'E_1': [18, 18, 20] }) # 定义列对映射 col_pairs = [('B', 'B_1'), ('C', 'C_1'), ('D', 'D_1'), ('E', 'E_1')] def generate_diff_tag(row): # 先判断A是否等于A_1 if row['A'] != row['A_1']: return '' # A不等时的标记,可按需修改 # 收集所有差异列名 diff_cols = [col for col, col1 in col_pairs if row[col] != row[col1]] return ','.join(diff_cols) # 生成新列 df['diff_tag'] = df.apply(generate_diff_tag, axis=1)
优化版(向量化,适合大数据集)
如果你的DataFrame数据量很大,行遍历的apply效率较低,可以改用向量化操作:
# 先标记A等于A_1的行 a_eq_mask = df['A'] == df['A_1'] # 初始化新列 df['diff_tag'] = '' # 遍历列对,批量更新标记 for col, col1 in col_pairs: # 筛选A相等且当前列对不等的行 mask = a_eq_mask & (df[col] != df[col1]) # 拼接列名到已有标记 df.loc[mask, 'diff_tag'] = df.loc[mask, 'diff_tag'].apply(lambda x: f'{x},{col}' if x else col) # A不等的行标记为空(可自定义) df.loc[~a_eq_mask, 'diff_tag'] = ''
说明
- 若需要处理
A≠A_1的情况,只需修改对应分支的返回值即可(比如返回'A') - 后续新增列对时,只需在
col_pairs列表中添加新的元组,无需修改核心逻辑
内容的提问来源于stack exchange,提问作者Adarsh Rajput
相关产品推荐
相关产品推荐

