
本文介绍如何使用 `map()` 配合 `combine_first()` 在 pandas 中精准更新县名字段:仅对字典中定义的代码进行重命名(如添加省份后缀),其余行保持原始县名不变,避免意外引入 nan。
在处理波兰行政区划数据时,常遇到同名县(如多个“Powiat brzeski”)因所属省份不同而需唯一标识的问题。理想做法是基于唯一编码(Code)将县名扩展为“县名_省份”格式,但直接使用 df['County'] = df['Code'].map(code_to_county) 会导致未匹配代码对应行的 County 值变为 NaN——这正是原始问题的核心缺陷。
根本原因在于:Series.map() 对字典中不存在的键默认返回 NaN,而原始 County 列中这些行的有效值被完全覆盖。解决的关键是保留原始值作为兜底,而非全量替换。
✅ 推荐方案:combine_first()
该方法将映射结果(含部分 NaN)与原始列进行“优先级合并”:以左侧 Series 为基准,仅在其值为 NaN 的位置,用右侧 Series 的对应值填充。语义清晰、性能高效、无需循环或条件判断。
import pandas as pd
# 示例数据
data = {
'Code': [1202000, 2402000, 802000, 3017000, 3005000, 9999999],
'County': ['Powiat brzeski', 'Powiat bielski', 'Powiat krośnieński',
'Powiat ostrowski', 'Powiat grodziski', 'Powiat ciechanowski']
}
df = pd.DataFrame(data)
# 映射字典:仅包含需增强的县(带省份后缀)
code_to_county = {
1202000: "Powiat brzeski_Malopolskie",
2402000: "Powiat bielski_Slaskie",
802000: "Powiat krośnieński_Lubuskie",
3017000: "Powiat ostrowski_Wielkopolskie",
3005000: "Powiat grodziski_Wielkopolskie"
}
# 安全更新:仅覆盖匹配项,其余保留原值
df['County'] = df['Code'].map(code_to_county).combine_first(df['County'])
print(df)输出结果:
Code County 0 1202000 Powiat brzeski_Malopolskie 1 2402000 Powiat bielski_Slaskie 2 802000 Powiat krośnieński_Lubuskie 3 3017000 Powiat ostrowski_Wielkopolskie 4 3005000 Powiat grodziski_Wielkopolskie 5 9999999 Powiat ciechanowski
? 补充说明与最佳实践:
- 为什么不用 fillna()? fillna() 虽可补 NaN,但若原始 County 列本身含 NaN,会错误覆盖;而 combine_first() 严格按索引对齐,更鲁棒。
- 扩展性建议:若映射逻辑复杂(如需查表、正则匹配),可改用 merge() 左连接替代 map(),同样配合 combine_first() 或 fillna() 处理缺失。
- 验证步骤:更新后建议执行 df[df['Code'].isin(code_to_county.keys())]['County'].str.contains('_') 快速校验增强是否生效。
此方法兼顾准确性与健壮性,是处理“选择性字段增强”场景的标准范式。










