
本文介绍如何高效、可复用地为包含国家名称的 Pandas DataFrame 自动添加“大洲”列,避免手动枚举所有国家,核心方法是通过权威公开数据源构建国家→大洲映射字典,并使用 map() 完成批量赋值。
本文介绍如何高效、可复用地为包含国家名称的 pandas dataframe 自动添加“大洲”列,避免手动枚举所有国家,核心方法是通过权威公开数据源构建国家→大洲映射字典,并使用 `map()` 完成批量赋值。
在数据分析中,常需将国家(Country)字段扩展为更高层级的地理维度(如大洲 Continent),以便进行分组统计、可视化或建模。手动维护国家-大洲对照表既易出错又难以维护,而借助结构化公开数据源自动生成映射字典,是专业且可持续的解决方案。
✅ 推荐方案:从权威网站动态抓取并构建映射字典
以下提供两种稳定可靠的来源方式(均基于 pandas.read_html 直接解析网页表格):
方式一:使用 StatisticsTimes(含完整国家名与大洲字段)
import pandas as pd
# 从 StatisticsTimes 抓取国家-大洲对照表(2024年仍有效)
url = 'https://statisticstimes.com/geography/countries-by-continents.php'
df_continent = pd.read_html(url)[2] # 第三张表格含完整信息
# 构建 {国家名: 大洲} 字典(注意列名需核对,此处为 'Country or Area' 和 'Continent')
country_to_continent = df_continent.set_index('Country or Area')['Continent'].to_dict()
# 应用到你的原始 DataFrame(假设国家列为 'country')
df['continent'] = df['country'].map(country_to_continent)
⚠️ 注意事项:
- 网页结构可能更新,建议首次运行时打印 df_continent.head() 确认列名;
- 部分国家名存在变体(如 “USA” vs “United States”),建议统一标准化(见下文)。
方式二:使用 country-code.cl(基于 ISO 两位码缩写映射)
# 该站点以 Continent 缩写(AS/EU/AF等)为主,需额外映射到全称
url = 'https://country-code.cl/'
df_code = pd.read_html(url, encoding='iso-8859-1', skiprows=12)[1]
# 构建缩写→全称映射
code_to_continent = {
'AS': 'Asia', 'EU': 'Europe', 'AF': 'Africa',
'OC': 'Oceania', 'NA': 'North America',
'SA': 'South America', 'AN': 'Antarctica'
}
# 生成 {国家名: 大洲} 字典(跳过 NaN 行)
country_to_continent = (
df_code.set_index('Name')['Continent']
.map(code_to_continent)
.dropna()
.to_dict()
)
? 关键增强技巧:提升鲁棒性
-
处理大小写与别名
实际数据中常出现缩写(如 "US")、全称("United States")或拼写差异。推荐预处理:# 标准化国家列(转小写 + 去空格),字典键也同步处理 df['country_clean'] = df['country'].str.strip().str.lower() d_clean = {k.lower().strip(): v for k, v in country_to_continent.items()} df['continent'] = df['country_clean'].map(d_clean) -
识别未匹配项并诊断
unmatched = df[df['continent'].isna()]['country'].unique() print("未匹配国家(共{}个):".format(len(unmatched)), list(unmatched)[:10])可据此补充字典或修正原始数据。
-
持久化字典(避免重复爬取)
import json with open('country_to_continent.json', 'w', encoding='utf-8') as f: json.dump(country_to_continent, f, ensure_ascii=False, indent=2) # 后续直接加载:with open(...) as f: d = json.load(f)
✅ 总结
无需硬编码数百个国家,只需一次网络请求即可生成完备映射;结合 map() 方法,实现零循环、高可读、易维护的大洲列添加。建议优先选用 StatisticsTimes 方式(字段语义清晰),并在生产环境中加入异常处理与缓存机制。最终结果列可直接用于 df.groupby('continent').sum() 等分析操作,大幅提升地理维度分析效率。










