Python中DataFrame映射:匹配code列并填充不匹配项
在Python中实现DataFrame的Code到Number映射(含缺失值处理)
首先,咱们先看看你的代码为什么不工作:你写的嵌套循环里,每次判断后都是直接给整个列赋值(First_table['sec_number'] = ...),而不是给当前匹配的那一行单元格赋值。这样循环结束后,所有行都会被最后一次循环的结果覆盖,自然得不到你想要的效果。
接下来分两部分回答你的问题:
一、如何通过迭代为特定单元格赋值(小数据量可用)
如果一定要用迭代的方式,你可以用iterrows()来遍历每一行,然后通过loc定位到具体单元格赋值。先初始化新列为默认值"Not match",再逐个匹配更新:
import pandas as pd # 先创建你的两个DataFrame(方便测试) First_table = pd.DataFrame({ 'name': ['Willard', 'Al', 'Omar', 'Spencer', 'Abin'], 'age': [20, 19, 22, 21, 18], 'grade': [88, 92, 95, 70, 76], 'code': [2877, 3000, 3710, 4001, 2338] }) Second_table = pd.DataFrame({ 'sec.Code': [2877, 1244, 3000, 2338, 4553], 'sec.number': [10003, 13772, 98822, 11223, 22996] }) # 初始化新列 First_table['sec.number'] = "Not match" # 逐行迭代更新 for idx, row in First_table.iterrows(): # 查找当前code对应的sec.number match_row = Second_table[Second_table['sec.Code'] == row['code']] if not match_row.empty: First_table.loc[idx, 'sec.number'] = match_row['sec.number'].iloc[0] print(First_table)
不过要注意:这种逐行迭代的方法效率很低,如果你的DataFrame有上万行甚至更多,运行速度会非常慢,因为pandas本来就是为矢量化操作设计的,逐行操作违背了它的设计初衷。
二、更高效的实现方式(推荐)
下面两种方法都是pandas的矢量化操作,速度快得多,代码也更简洁:
方法1:使用map() + 字典映射
先把第二个表转换成{code: number}的字典,然后用map()函数完成映射,缺失值直接用get()方法填充为"Not match":
# 创建映射字典 code_number_map = Second_table.set_index('sec.Code')['sec.number'].to_dict() # 完成映射 First_table['sec.number'] = First_table['code'].map(lambda x: code_number_map.get(x, "Not match")) print(First_table)
方法2:使用merge()左连接
用左连接保留第一个表的所有行,然后把缺失的sec.number填充为"Not match":
# 左连接两个表,匹配code和sec.Code merged_df = First_table.merge( Second_table, left_on='code', right_on='sec.Code', how='left' ) # 填充缺失值 merged_df['sec.number'] = merged_df['sec.number'].fillna("Not match") # 移除多余的sec.Code列(如果不需要的话) merged_df = merged_df.drop('sec.Code', axis=1) print(merged_df)
这两种方法都能快速得到你想要的结果,其中map()方法代码最简洁,适合这种简单的一对一映射场景;merge()方法更灵活,适合需要处理更复杂连接逻辑的情况。
内容的提问来源于stack exchange,提问作者RGRGRG
相关产品推荐
相关产品推荐

