Python Pandas动态匹配列值并返回对应行指定列值的方法
高效实现动态FG/PID列匹配方案
针对你遇到的动态数量FG_x/PID_x列匹配需求,这里提供两种高效的实现方案,无需依赖固定列数的np.select()或低效循环:
方案一:长表重塑匹配(逻辑清晰,易维护)
通过将宽表转为长表,统一匹配逻辑,完全不受列数变化影响:
示例代码
import pandas as pd import numpy as np # 模拟你的动态列数据 df = pd.DataFrame({ 'Main_FG': ['A', 'B', 'C', 'A'], 'FG_1': ['A', 'D', 'C', 'E'], 'FG_2': ['B', 'B', 'F', 'A'], 'FG_3': ['C', 'E', 'G', 'H'], 'PID_1': [101, 104, 107, 110], 'PID_2': [102, 105, 108, 111], 'PID_3': [103, 106, 109, 112] }) # 自动识别FG和PID列 fg_cols = [col for col in df.columns if col.startswith('FG_')] pid_cols = [col for col in df.columns if col.startswith('PID_')] # 将FG列转为长表,提取序号 fg_melt = df[['Main_FG'] + fg_cols].melt( id_vars=['Main_FG'], var_name='fg_col', value_name='FG_value' ) fg_melt['seq'] = fg_melt['fg_col'].str.extract(r'(\d+)').astype(int) # 将PID列转为长表,提取序号 pid_melt = df[pid_cols].melt( var_name='pid_col', value_name='PID_value' ) pid_melt['seq'] = pid_melt['pid_col'].str.extract(r'(\d+)').astype(int) # 合并匹配,按行索引和序号关联 matched = fg_melt.merge(pid_melt, left_index=True, right_index=True, on='seq') # 筛选匹配行,每行取第一个匹配的PID result = matched[matched['Main_FG'] == matched['FG_value']].groupby(level=0)['PID_value'].first() # 合并回原表 df['Matched_PID'] = result
方案二:Numpy向量匹配(性能最优,适合大数据)
利用Numpy的广播和矩阵索引,完全避免循环,处理大数据集时效率极高:
示例代码
import pandas as pd import numpy as np # 同样使用上面的示例df fg_cols = [col for col in df.columns if col.startswith('FG_')] pid_cols = [col for col in df.columns if col.startswith('PID_')] # 转为Numpy数组,实现广播比较 fg_array = df[fg_cols].to_numpy() pid_array = df[pid_cols].to_numpy() main_fg_array = df['Main_FG'].to_numpy()[:, np.newaxis] # 生成每行的匹配掩码:FG_x == Main_FG的位置 match_mask = (fg_array == main_fg_array) # 找到每行第一个匹配的索引,处理无匹配的情况 match_indices = match_mask.argmax(axis=1) # 无匹配的行索引设为-1,后续填充NaN match_indices[~match_mask.any(axis=1)] = -1 # 提取对应PID值 df['Matched_PID'] = np.where( match_mask.any(axis=1), pid_array[np.arange(len(df)), match_indices], np.nan )
关键说明
- 两种方案都自动识别
FG_*和PID_*列,无需硬编码列数 - 若同一行存在多个
FG_x等于Main_FG,两种方案均取第一个匹配的PID_x,可根据需求调整为取最后一个或其他逻辑 - 无匹配的行将填充
NaN,可修改np.where的第三个参数自定义默认值
内容的提问来源于stack exchange,提问作者Python_Learner
相关产品推荐
相关产品推荐

