Python 字符串匹配的矢量化
问题: 是否可以对两个数据帧/系列的字符串匹配进行矢量化 概念: 我有两个数据帧(df_地址,df_世界城市):Python 字符串匹配的矢量化,python,pandas,Python,Pandas,问题: 是否可以对两个数据帧/系列的字符串匹配进行矢量化 概念: 我有两个数据帧(df_地址,df_世界城市): df_地址:包含一列地址数据(如“Sherlock Str;Paris;”) df_world_city:包含一列城市名称和相应国家(“FRA”、“巴黎”) 我浏览了每个地址,并试图与所有城市进行匹配,找出地址中提到的城市,并将相应的国家添加到地址中。匹配的城市保存在一个列表中,列表是以国家为键的字典值({'FRA':['Paris']}) 目前,我主要使用for循环遍历地址和城市以
def regex_city_matching(target, location):
if type(target) != str or type(location) != str or len(target) <= 3:
# Skip NaN and to short cities
return False
# Match city only as full word, not a substring of another word
pattern = re.compile('(^|[\W])' + re.escape(target) + '($|[\W])', re.IGNORECASE)
result = re.search(pattern, location)
if result:
return True
return False
def city_matching_no_country_multi_dict_simple(self, df_world_city, df_address):
col_names = ['node_id', 'name', 'city_iso']
df_matched_city_no_country = pd.DataFrame(columns=col_names)
for index_city in df_world_city.index:
# Iterate over each city
w_city = df_world_city.at[index_city, 'city']
if type(w_city) != str or len(w_city) <= 3:
# Skip NaN and to short cities
continue
w_country = df_world_city.at[index_city, 'iso']
for ind_address in df_address.index:
if self.regex_city_matching(w_city, df_address.at[ind_address, 'name']):
node_id = df_address.at[ind_address, 'node_id']
address = df_address.at[ind_address, 'name']
if (df_matched_city_no_country['node_id'] == node_id).any():
# append new city / country
ind_append_address = df_matched_city_no_country.loc[df_matched_city_no_country.node_id == node_id].index[0]
if w_country in df_matched_city_no_country.at[ind_append_address, 'city_iso']:
# Country in dictionary
df_matched_city_no_country.at[ind_append_address, 'city_iso'][w_country].append(w_city)
else:
# Country not in dictionary
df_matched_city_no_country.at[ind_append_address, 'city_iso'][w_country] = [w_city]
else:
# add new address with city / country
dict_iso_city = {w_country: [w_city]}
df_matched_city_no_country = df_matched_city_no_country.append(
{'node_id': node_id, 'name': address, 'city_iso': dict_iso_city},
ignore_index=True)
return df_matched_city_no_country
def regex\u city\u匹配(目标、位置):
如果类型(目标)!=str或类型(位置)!=str或len(target)您应该使用{'city':'COUNTRY',}
创建一个反向字典,这样您就不必循环,只需在常量(O(1))时间内直接访问即可
除此之外,我会对已知的城市进行set()
,这样我就不必循环任何东西,只需快速查找,我就知道这个城市是否未知
最后,我将简化地址解析,而不使用非常昂贵的正则表达式,将所有字符转换为大写或小写,将非字母字符替换为空格,只需.split()
即可获得一个单词列表,而不是您现在正在做的事情
一旦你做了所有这些更改,处理160k个地址和200万个已知城市可能需要10-15秒
请告诉我您是否需要代码示例?谢谢1.为什么要颠倒口述?我真的不想再重复一遍?!--2.一组城市听起来不错,但是:我在不同的国家多次拥有一些城市,我如何知道为什么这个城市来自哪个国家?--3.Split听起来不错,但是你能提供一些例子吗?我将如何通过列表来匹配我的城市?再次感谢:)@user3388671您现在如何处理不同国家的相同城市?我将每个城市视为唯一的,因为在另一列中,“iso”是国家代码。因此,如果一个城市匹配,我使用城市索引将国家代码分配给w_country。您能否提供一个代码示例,说明如何有效地迭代拆分的地址,并在设置的“世界城市”中进行检查。@user3388671如果您有国家代码,为什么需要搜索城市,只需根据国家代码获取国家,而不管是哪个城市?其目的是从数据中获取国家和城市。有明确国家名称的地址我很容易就能得到。下一步是获取该地址的城市,因为我只匹配匹配国家的城市。当前函数的最后一步和思想是从数据中获取城市,并根据匹配的城市识别地址所在的国家,即使没有写出来。但假阳性点击的数量是极端的,结果是可用的。