我有大约15,000个观测值的数据集。该观察结果是来自世界各地的城市名称。这个数据集已经被来自许多不同国家的人们所填充,这意味着我用相同的语言用相同的语言重复了几个城市。参见下面的DF提取:
city_name
bruselas
brussel
brussels
brussels
brussels auderghem
bruxelles
bruxelles belgium
munchen
munchenstein
munchwilen
munderkingen
mundolsheim
mungia
munguia
munich
munich
munich
munich germany
munich munchen
munich rupert mayer strasse
任务是将DF中的所有城市都映射到其英文名称,但是,由于这些城市的格式和语言不同,因此我发现很难找到一种解决方案,除了手动执行此任务外,这是我们要进行15,000多个观察,因此效率不高。最终数据集应如下所示(仅使用上面的一些观察结果):
city_name mapped_city
brussels auderghem Brusels
bruxelles Brusels
bruxelles belgium Brusels
munchen Munich
munich germany Munich
任何帮助将不胜感激
答案 0 :(得分:3)
使用使用Levenshtein distance algorithm
的Fuzzy Wuzzyimport pandas as pd
from fuzzywuzzy import process, fuzz
df = pd.read_clipboard(sep='\t')
print(df.head(5))
0 brussels
1 auderghem
2 bruxelles
3 bruxelles
4 belgium
我们需要一个城市的主列表来用作查找,我假设您知道城市是什么,我将使用github中的这个城市。
cities = pd.read_csv('https://datahub.io/core/world-cities/r/0.csv')
choices = df['City Names'].to_dict()
lookups = cities['name'].tolist()
res = [(lookup,) + item for lookup in lookups for item in process.extract(lookup, choices,limit=2)]
df = pd.DataFrame(res, columns=["lookup", "matched", "score", "idx"])
print(df)
lookup matched score idx
9401 Munich munich 100 13
12612 Mungia mungia 100 10
9400 Munich munich 100 12
1820 Brussels brussels 100 0
12613 Mungia munguia 92 11
... ... ... ... ...
27205 Желино auderghem 0 1
27204 Желино brussels 0 0
27487 Зуунмод auderghem 0 1
27486 Зуунмод brussels 0 0
27212 Теарце brussels 0 0
自然地,如果您事先编辑查找数据框以仅将您知道的城市保留在列表中,那么这将使查找运行更快并返回所需的结果。
例如,e
lookups = ['brussels','munich']
print(df.sort_values('score',ascending=False))
lookup matched score idx
0 brussels brussels 100 0
2 munich munich 100 12
3 munich munich 100 13
1 brussels bruxelles 71 2
然后您可以以最高分进行查找。
希望这会为您指明正确的方向。我不是这个库的专家,所以最好仔细阅读您的用例文档以优化代码。 祝你好运。
答案 1 :(得分:3)
您可以只使用Google Maps或OpenStreetMap来搜索那些地方并查看它们返回的内容。两者似乎都能处理带有或不带有国家/地区的不同语言(例如慕尼黑/慕尼黑,北京/北京)的查询,以及某些拼写错误(例如不带“ü”的“ munchen”)。
AFAIK,Google Maps API并非免费使用,但OSM API应该是免费的,在任何情况下,您都可以同时发出GET请求并解析结果。例如,对于OpenStreetMap:
import requests, re, json
lst = {'bruxelles', 'munguia', 'munich rupert mayer strasse', 'munchen',
'mundolsheim', 'munchenstein', 'munich', 'brussels', 'munich germany',
'bruselas', 'brussels auderghem ', 'munderkingen', 'mungia',
'munchwilen', 'bruxelles belgium', 'munich munchen ', 'brussel'}
query = "https://nominatim.openstreetmap.org/search.php?q=%s"
for x in lst:
response = requests.get(query % x)
matches = re.findall(r'"placename": (".*?"),', response.text)
print(x, "-->", json.loads(matches[0]))
结果不完美,例如一些结果过于具体,但您可以使用其他属性,例如“类型”(可能应该是“城市”)。通过一些清理和更多的修补工作,这应该可以帮助您开始。
munich --> München
munderkingen --> Munderkingen
munich munchen --> Johanniter-Unfall-Hilfe e.V., Regionalgeschäftsstelle
mungia --> Mungia
brussels auderghem --> Auderghem - Oudergem
munchwilen --> Münchwilen
bruselas --> Bruxelles / Brussel
bruxelles --> Bruxelles / Brussel
munguia --> Mungia
munich rupert mayer strasse --> Rupert-Mayer-Straße
mundolsheim --> Mundolsheim
bruxelles belgium --> Bruxelles / Brussel
munchen --> München
brussels --> Bruxelles / Brussel
munchenstein --> Münchenstein
munich germany --> München
brussel --> Bruxelles / Brussel
对于Google Maps,同样的请求也应如此,但结果似乎不像使用OSM那样容易解析。
(免责声明:如果您向15k这样的请求发送垃圾邮件,不确定它们是否太激动了,您可能希望将其散布开来,或者使用比HTTP请求更多的官方API。您绝对应该缓存的结果两者均完整完成搜索查询(以调整要使用的属性而无需再次查询)以及在用户指定城市重复的情况下映射的城市,以最大程度地减少请求数,从而最大程度地减少服务器负载和运行时间。) / p>
答案 2 :(得分:-1)
尝试按城市的首字母进行映射,以减轻工作量