Python提取城市后自动匹配对应州省与国家的实现方法
Python位置实体层级关联补全方案
问题根源
现有代码将国家、城市、州/省三类数据拆分为独立平级列表存储,完全丢失了三者之间的行政从属映射关系,仅能判断字符串是否属于某类地理位置,无法关联到其上级行政单位,自然无法实现自动补全。
实现步骤
- 重构数据源存储结构
废弃原有拉平平级列表的存储逻辑,构建两类键值对映射表作为查找依据:city_to_meta:键为城市名称,值存储该城市所属的州/省、国家信息state_to_country:键为州/省名称,值存储该州/省所属的国家信息
注意:原有手动维护的州/省仅存名称列表,没有从属关联,需要先补全为「州名-所属国家-下辖城市」的结构化映射,否则关联逻辑没有数据支撑。重名城市问题可在后续匹配环节加歧义判断,初期可优先匹配第一条有效映射。
- 初始化映射表参考代码:
import requests from geotext import GeoText import locationtagger # 拉取国家-城市基础数据 response = requests.get("https://countriesnow.space/api/v0.1/countries") json_response = response.json() # 初始化映射容器和校验集合 city_to_meta = {} state_to_country = {} all_countries = set() all_states = set() all_cities = set() # 处理API返回的国家、城市数据 for country_item in json_response['data']: country_name = country_item['country'] all_countries.add(country_name) for city_name in country_item['cities']: all_cities.add(city_name) if city_name not in city_to_meta: city_to_meta[city_name] = {"state": "NA", "country": country_name} # 加载手动维护的州/省映射,替换原有'states list',按实际数据补全即可 states_map = { "Tamil Nadu": { "country": "India", "cities": ["Chennai", "Coimbatore", "Madurai"] } # 其余州/省按相同格式补充 } # 填充州相关映射 for state_name, state_info in states_map.items(): all_states.add(state_name) state_to_country[state_name] = state_info["country"] for city_name in state_info["cities"]: all_cities.add(city_name) if city_name in city_to_meta: city_to_meta[city_name]["state"] = state_name else: city_to_meta[city_name] = {"state": state_name, "country": state_info["country"]}
- 重写匹配补全逻辑
保留原有NLP实体提取逻辑,提取到原始实体后按照层级关系补全缺失字段:先通过匹配到的城市补全州、国家信息,再通过匹配到的州补全国家信息,最后做去重和空值处理,和原有输出格式对齐。参考代码:
def extract_location(str_text): # 提取原始地理位置实体 places = GeoText(str_text) raw_cities = [c for c in places.cities if c in all_cities] place_entity = locationtagger.find_locations(text=str_text) raw_states = [s for s in place_entity.regions if s in all_states] raw_countries = [c for c in places.countries if c in all_countries] # 用集合存储结果自动去重 final_cities = set(raw_cities) final_states = set(raw_states) final_countries = set(raw_countries) # 通过城市补全对应州、国家 for city in final_cities: city_meta = city_to_meta.get(city, {}) if city_meta.get("state") != "NA": final_states.add(city_meta["state"]) if city_meta.get("country"): final_countries.add(city_meta["country"]) # 通过州补全对应国家 for state in final_states: match_country = state_to_country.get(state) if match_country: final_countries.add(match_country) # 空值兼容,和原有逻辑保持一致 city_result = list(final_cities) if final_cities else "NA" state_result = list(final_states) if final_states else "NA" country_result = list(final_countries) if final_countries else "NA" return [ {"Location": {"City": city_result, "State": state_result, "Country": country_result}} ]
- 可选优化:处理重名歧义
若后续遇到同名城市/州分属不同行政区域的情况,可增加匹配优先级:如果文本中已经提取到明确的国家/州实体,优先匹配和已提取实体从属关系一致的映射,避免归属匹配错误。
注意事项
如果不想长期手动维护州/省和城市的从属映射,可以替换为自带行政层级关系的地理位置数据源,降低人工维护成本。
内容的提问来源于stack exchange,提问作者vinoth kumar
相关产品推荐
相关产品推荐

