基于Code列匹配从另一DataFrame添加MLC Code列(求低时间复杂度方案)
高效实现DataFrame间值映射的方案
你的嵌套循环方案时间复杂度是O(len(df2)*len(df1)),数据量一大必然卡顿。Pandas提供了原生的向量化操作和索引优化方案,能把时间复杂度降到接近线性的水平,下面分两种场景给出解决方案:
场景1:不限制匹配次数(所有匹配的Code都对应MLC值)
这种情况用map方法最高效,先把df1转换成Code到MLC Code的字典,再直接映射到df2:
import pandas as pd # 构造示例数据 df1 = pd.DataFrame({'Code': [1,2,8,4], 'MLC Code': [8,66,62,66]}) df2 = pd.DataFrame({'Code': [1,2,3,4,4,8]}) # 构建Code到MLC Code的映射字典(若df1有重复Code,会保留最后一条的MLC值) code_mlc_map = df1.set_index('Code')['MLC Code'].to_dict() # 映射到df2,不匹配的自动填充NaN df2['MLC Code'] = df2['Code'].map(code_mlc_map)
运行后结果:
| Code | MLC Code |
|---|---|
| 1 | 8 |
| 2 | 66 |
| 3 | NaN |
| 4 | 66 |
| 4 | 66 |
| 8 | 62 |
场景2:每个df1的Code仅匹配一次(对应你给出的期望结果)
如果需要像你期望的那样,df1里的每个Code只能给df2的一个匹配项赋值,剩下的匹配项留空,可以通过标记已匹配行+索引加速实现:
import pandas as pd df1 = pd.DataFrame({'Code': [1,2,8,4], 'MLC Code': [8,66,62,66]}) df2 = pd.DataFrame({'Code': [1,2,3,4,4,8]}) # 给df1添加匹配标记列,并给Code列加索引加速查找 df1['matched'] = False df1 = df1.set_index('Code') # 初始化MLC Code列为空值 df2['MLC Code'] = pd.NA # 遍历df2,查找未被匹配的对应Code for idx, code in df2['Code'].items(): if code not in df1.index: continue # 筛选当前Code下未匹配的行 available_rows = df1.loc[code][~df1.loc[code]['matched']] if not available_rows.empty: # 取第一个可用行的MLC值 if isinstance(available_rows, pd.Series): mlc_value = available_rows['MLC Code'] df1.at[code, 'matched'] = True else: mlc_value = available_rows.iloc[0]['MLC Code'] df1.loc[available_rows.index[0], 'matched'] = True # 赋值给df2 df2.at[idx, 'MLC Code'] = mlc_value
运行后就能得到你给出的期望结果:
| Code | MLC Code |
|---|---|
| 1 | 8 |
| 2 | 66 |
| 3 | |
| 4 | 66 |
| 4 | |
| 8 | 62 |
原代码的问题说明
- 你用了
==比较运算符而非=赋值,根本没把值写到df2里; - 直接用
df2["MLC Code"][i]链式索引赋值会触发SettingWithCopyWarning,建议用.at或.loc来安全赋值。
内容的提问来源于stack exchange,提问作者Monil Shah
相关产品推荐
相关产品推荐

