Python 3中提取DataFrame列内提及的所有国家及次数问题求助
解决DataFrame列中提取所有提及国家(含重复)的问题
我来帮你搞定这个问题!你之前用GeoText会自动去重同一行里的国家,用pycountry的实现又只能返回第一个匹配的结果,刚好踩中了两个工具的局限性。下面给你一个完全符合需求的解决方案:
核心思路
我们需要实现三个关键点:
- 处理国家缩写(比如把USA转换成United States,让pycountry能识别)
- 遍历每行文本,找出所有匹配的国家,不能只取第一个
- 保留国家出现的顺序和重复次数(比如两行中国就返回
['China','China'])
完整代码实现
首先确保你安装了依赖:
pip install pycountry pandas
然后是可直接运行的代码:
import pandas as pd import pycountry # 你的测试数据集 sample_data = [ ['[Aydemir, Deniz\', \' Gunduz, Gokhan\', \' Asik, Nejla] Bartin Univ, Fac Forestry, Dept Forest Ind Engn, TR-74100 Bartin, Turkey\', \' [Wang, Alice] Lulea Univ Technol, Wood Technol, Skelleftea, Sweden',1990], ['[Fang, Qun\', \' Cui, Hui-Wang] Zhejiang A&F Univ, Sch Engn, Linan 311300, Peoples R China\', \' [Du, Guan-Ben] Southwest Forestry Univ, Kunming 650224, Yunnan, Peoples R China',2005], ['[Blumentritt, Melanie\', \' Gardner, Douglas J.\', \' Shaler, Stephen M.] Univ Maine, Sch Resources, Orono, ME USA\', \' [Cole, Barbara J. W.] Univ Maine, Dept Chem, Orono, ME 04469 USA',2012] ] df = pd.DataFrame(sample_data, columns=['Authors', 'Year']) # 自定义缩写映射表,可根据需求扩展 country_abbreviations = { "USA": "United States", "UK": "United Kingdom", "TR": "Turkey" # 对应示例中的TR-74100邮编前缀 } def extract_all_countries(text): # 第一步:替换所有国家缩写为完整名称 for abbr, full_name in country_abbreviations.items(): # 用边界匹配避免误替换(比如不会把"USAbc"里的USA换掉) text = text.replace(f" {abbr} ", f" {full_name} ") # 处理文本首尾的特殊情况 if text.startswith(f"{abbr} "): text = text.replace(f"{abbr} ", f"{full_name} ", 1) if text.endswith(f" {abbr}"): text = text.replace(f" {abbr}", f" {full_name}", 1) lower_text = text.lower() matched_countries = [] # 第二步:遍历所有国家,统计出现次数并添加到结果列表 for country in pycountry.countries: country_name_lower = country.name.lower() # 用空格包裹确保匹配完整词(避免把"Chin"当成"China") occurrence_count = lower_text.count(f" {country_name_lower} ") if occurrence_count > 0: # 出现几次就添加几次,保留重复 matched_countries.extend([country.name] * occurrence_count) return matched_countries # 应用到DataFrame的Authors列 df['Extracted_Countries'] = df['Authors'].apply(extract_all_countries) # 查看结果 print(df['Extracted_Countries'])
代码细节说明
- 缩写处理:通过
country_abbreviations字典统一转换缩写,解决了GeoText识别不了USA这类缩写的问题,而且你可以随时添加更多缩写规则 - 完整词匹配:用
{country_name_lower}前后加空格的方式,避免误匹配到包含国名字符的其他词汇(比如不会把"Chin"识别成"China") - 保留重复:用
extend([country.name] * occurrence_count)把每个出现的国家都添加到结果里,完美实现你要的['China','China']这种输出 - 兼容性:pycountry的国家数据是标准化的,比GeoText更全面,能识别更多国家名称
运行结果
执行代码后,你会得到完全符合预期的输出:
0 [Turkey, Sweden] 1 [China, China] 2 [United States, United States] Name: Extracted_Countries, dtype: object
内容的提问来源于stack exchange,提问作者mandella




