如何用Pandas根据另一DataFrame列的列表更新DataFrame行
问题描述
现有两个Pandas DataFrame:
# df1 0 1 2 ECID 0 0 0 0 00 1 0 0 0 01 2 0 0 0 02 # df2 ECID FailPattern 0 00 [1, 2] 1 01 [1] 2 02 [0]
需要根据df2的FailPattern列,将df1中对应ECID行的指定列(列号与FailPattern中的元素匹配)数值更新为1,最终得到如下结果:
0 1 2 ECID 0 0 1 1 00 1 0 1 0 01 2 1 0 0 02
解决方案
方法一:合并后逐行更新(直观易懂)
先通过ECID合并两个DataFrame,再遍历行根据FailPattern修改对应列的值:
import pandas as pd # 构造示例数据 df1 = pd.DataFrame({'0': [0,0,0], '1': [0,0,0], '2': [0,0,0], 'ECID': ['00','01','02']}) df2 = pd.DataFrame({'ECID': ['00','01','02'], 'FailPattern': [[1,2], [1], [0]]}) # 按ECID合并 merged_df = df1.merge(df2, on='ECID') # 遍历更新每一行 for idx, row in merged_df.iterrows(): for col_idx in row['FailPattern']: merged_df.loc[idx, str(col_idx)] = 1 # 移除临时列,得到结果 result_df = merged_df.drop('FailPattern', axis=1) print(result_df)
方法二:Explode+透视表(高效无循环)
利用Pandas向量化操作替代循环,适合大数据量场景:
import pandas as pd df1 = pd.DataFrame({'0': [0,0,0], '1': [0,0,0], '2': [0,0,0], 'ECID': ['00','01','02']}) df2 = pd.DataFrame({'ECID': ['00','01','02'], 'FailPattern': [[1,2], [1], [0]]}) # 将FailPattern展开为单行对应单个列索引的格式 exploded_df = df2.explode('FailPattern') exploded_df['FailPattern'] = exploded_df['FailPattern'].astype(str) # 转为字符串匹配df1列名 exploded_df['value'] = 1 # 透视表转为宽表,匹配df1结构 pivot_df = exploded_df.pivot(index='ECID', columns='FailPattern', values='value').fillna(0) # 合并并覆盖原df1的列值,恢复原列顺序 result_df = df1.set_index('ECID').combine_first(pivot_df).reset_index() result_df = result_df[df1.columns] print(result_df)
方法三:Apply函数批量处理
通过字典映射快速查找对应故障列,再用apply逐行更新:
import pandas as pd df1 = pd.DataFrame({'0': [0,0,0], '1': [0,0,0], '2': [0,0,0], 'ECID': ['00','01','02']}) df2 = pd.DataFrame({'ECID': ['00','01','02'], 'FailPattern': [[1,2], [1], [0]]}) # 将df2转为ECID到故障列的字典映射 fail_map = df2.set_index('ECID')['FailPattern'].to_dict() # 定义行处理函数 def update_row(row): fail_cols = fail_map[row['ECID']] for col in fail_cols: row[str(col)] = 1 return row # 应用函数到所有行 result_df = df1.apply(update_row, axis=1) print(result_df)
内容的提问来源于stack exchange,提问作者Nandeep Devendra
相关产品推荐
相关产品推荐

