【发布时间】:2018-07-06 15:30:29
【问题描述】:
问题: 是否可以向量化两个 DataFrames/Series 的字符串匹配?
概念: 我有两个 DataFrame(df_address、df_world_city):
- df_address:包含一列地址数据(例如“Sherlock Str.; Paris;”)
- df_world_city:包含一个包含城市名称和相应国家/地区(“FRA”、“Paris”)的列
我遍历每个地址并尝试匹配所有城市,以找出地址中提到的城市并将相应的国家添加到其中。匹配的城市保存在一个列表中,该列表是以国家为键的字典的值({'FRA': ['Paris']})。
目前,我主要使用 for 循环来遍历地址和城市以匹配它们。多处理(48 个进程)和大量数据(df_address:160,000 行;df_wordl_city:2,200,000 行)大约需要 4-5 天。
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
编辑: 谢谢@lenik!与一组城市的匹配效率更高,而且完成得非常快。
但并没有完全实现,因为测试表明误报率很高。
【问题讨论】: