Pandas匹配列值生成对应结果列表问题求助
问题分析与解决
原代码的问题
- 内层循环仅检查
list2的第一行,一旦不匹配就直接添加旧值并终止循环,未遍历list2所有行寻找匹配项 - 匹配时错误地将整列
list2['New Bewehrungsgehalt']添加到列表,而非对应行的单个值 list2去重时的subset参数写错,应为'Positionsnummer'而非'IPositionsnummer'
解决方案
方法1:优化循环逻辑
修正循环逻辑,为每个list1的元素先预设默认旧值,再遍历list2查找匹配项,找到则替换为新值,确保每个list1元素仅生成一个结果:
import pandas as pd list1 = pd.read_excel(r"C:\Users\kuk\Downloads\Dynamo\dummy.xlsx", sheet_name='Sheet1') list2 = pd.read_excel(r"C:\Users\kuk\Downloads\Dynamo\dummy.xlsx", sheet_name='Sheet2') # 修正去重参数错误,重置索引时丢弃原索引 list2 = list2.dropna(subset=['Positionsnummer']).drop_duplicates(subset=['Positionsnummer']).reset_index(drop=True) value = [] # 遍历list1的每一行 for idx, row in list1.iterrows(): # 预设默认旧值,这里取list2中第一个旧值,可根据需求改为固定值 default_val = list2['Bewehrungsgehalt'].iloc[0] matched = False # 遍历list2找匹配项 for j in range(len(list2)): if row["ID"] == list2["Positionsnummer"][j]: value.append(list2['New Bewehrungsgehalt'][j]) matched = True break # 未找到匹配则添加默认值 if not matched: value.append(default_val) # 验证长度是否一致 print(len(value) == len(list1)) # 输出应为True
方法2:使用Pandas高效匹配(推荐)
利用Pandas内置的map或merge功能,比循环更高效简洁,适合处理大数据量:
方式A:使用map映射
先将list2转换为匹配字典,再用map快速匹配,未匹配项用默认旧值填充:
import pandas as pd list1 = pd.read_excel(r"C:\Users\kuk\Downloads\Dynamo\dummy.xlsx", sheet_name='Sheet1') list2 = pd.read_excel(r"C:\Users\kuk\Downloads\Dynamo\dummy.xlsx", sheet_name='Sheet2') # 清洗list2:去空值、去重 list2_clean = list2.dropna(subset=['Positionsnummer']).drop_duplicates(subset=['Positionsnummer']) # 构建{编号:新值}的匹配字典 pos_dict = dict(zip(list2_clean['Positionsnummer'], list2_clean['New Bewehrungsgehalt'])) # 生成结果:匹配则取新值,否则用默认旧值 default_old_val = list2_clean['Bewehrungsgehalt'].iloc[0] list1['value'] = list1['ID'].map(pos_dict).fillna(default_old_val) # 转换为列表格式(若需要) value = list1['value'].tolist() print(len(value) == len(list1)) # 输出应为True
方式B:使用left_merge左连接
通过左连接关联两个表,再填充未匹配的空值:
import pandas as pd list1 = pd.read_excel(r"C:\Users\kuk\Downloads\Dynamo\dummy.xlsx", sheet_name='Sheet1') list2 = pd.read_excel(r"C:\Users\kuk\Downloads\Dynamo\dummy.xlsx", sheet_name='Sheet2') # 清洗list2:去空值、去重 list2_clean = list2.dropna(subset=['Positionsnummer']).drop_duplicates(subset=['Positionsnummer']) # 左连接,按ID和Positionsnummer匹配 merged = list1.merge(list2_clean, left_on='ID', right_on='Positionsnummer', how='left') # 生成结果:有匹配则取新值,否则用默认旧值 default_old_val = list2_clean['Bewehrungsgehalt'].iloc[0] merged['value'] = merged['New Bewehrungsgehalt'].fillna(default_old_val) # 转换为列表格式(若需要) value = merged['value'].tolist() print(len(value) == len(list1)) # 输出应为True
关键说明
- 修正了
list2去重时的参数错误,确保基于Positionsnummer去重 - 所有方案都保证最终
value的长度与list1完全一致 - Pandas内置方法(
map/merge)比循环效率更高,尤其适合处理较大规模的数据集
内容的提问来源于stack exchange,提问作者Kuladeep
相关产品推荐
相关产品推荐

