Pandas实现单行多组列对比及自定义规则结果标记
问题解决:按组对比列生成结果标记
源数据
data = { 'id': [1,2,3,4,5], '1_src1': ['a', 'b','c', 'd', 'e'] , '1_src2': ['a', 'b','c', 'd', 'e'] , '2_src1': ['a', 'b','f', 'd', 'e'] , '2_src2': ['a', 'b','c', 'd', 'e'] , '3_src1': ['a', 'b','c', 'd', 'e'] , '3_src2': ['a', 'b','1', 'd', 'm'] } pd.DataFrame(data)
需求说明
- 首列为固定名称
id,需按列位置将其余列每两列为一组对比(第2与第3列、第4与第5列等),列名可变化。 - 规则:若除最后n组外任意一组对比失败,
res标记为1;若最后n组存在失败(且前面组都成功),res标记为2;全部成功则标记为0。 - 预期生成含
id和res的结果DataFrame。
已尝试代码
cols_comp = [] for i in range(0,len(x),2): cols_comp.append(x[i:i+2])
已完成列分组,但无法推进后续逻辑,寻求解决方案。
解决方案
直接上完整代码,支持自定义最后n组的判断,一步到位实现需求:
import pandas as pd data = { 'id': [1,2,3,4,5], '1_src1': ['a', 'b','c', 'd', 'e'] , '1_src2': ['a', 'b','c', 'd', 'e'] , '2_src1': ['a', 'b','f', 'd', 'e'] , '2_src2': ['a', 'b','c', 'd', 'e'] , '3_src1': ['a', 'b','c', 'd', 'e'] , '3_src2': ['a', 'b','1', 'd', 'm'] } df = pd.DataFrame(data) # 自定义参数:最后n组,这里设为1,可根据需求调整 n = 1 # 取出id之外的所有列,按每两列一组拆分 compare_cols = df.columns.drop('id') cols_groups = [compare_cols[i:i+2] for i in range(0, len(compare_cols), 2)] # 生成每组的对比结果:True代表该行两列值不一样 group_diff = [] for col_pair in cols_groups: group_diff.append(df[col_pair[0]] != df[col_pair[1]]) # 把每组结果转成每行对应各组的差异情况 diff_df = pd.DataFrame(group_diff).T # 按规则给每行打标记 def mark_res(row): # 检查除最后n组外的其他组有没有差异,避免分组总数小于n时出错 has_prev_diff = row.iloc[:-n].any() if len(row) > n else False # 检查最后n组有没有差异 has_last_diff = row.iloc[-n:].any() if has_prev_diff: return 1 elif has_last_diff: return 2 else: return 0 # 生成res列,只保留id和res df['res'] = diff_df.apply(mark_res, axis=1) final_df = df[['id', 'res']] print(final_df)
代码解释
- 列分组:用列表推导式替代原循环,快速把要对比的列按两两分组,写法更简洁高效。
- 组内对比:遍历每组列,生成布尔值序列,标记每行两列值是否不等。
- 标记规则实现:
- 通过
n参数可灵活设置“最后n组”的数量; - 只要前面(除最后n组外)任意一组存在不等,直接标记为1;
- 前面组全相等但最后n组存在不等,标记为2;
- 所有组都相等则标记为0;
- 增加了分组总数小于n的边界判断,避免报错。
- 通过
- 结果输出:提取
id和res列,得到完全符合需求的结果DataFrame。
内容的提问来源于stack exchange,提问作者usr_lal123
相关产品推荐
相关产品推荐

