Python 字符串匹配的矢量化

Python 字符串匹配的矢量化,python,pandas,Python,Pandas,问题: 是否可以对两个数据帧/系列的字符串匹配进行矢量化 概念: 我有两个数据帧(df_地址,df_世界城市): df_地址:包含一列地址数据(如“Sherlock Str;Paris;”) df_world_city:包含一列城市名称和相应国家(“FRA”、“巴黎”) 我浏览了每个地址,并试图与所有城市进行匹配,找出地址中提到的城市,并将相应的国家添加到地址中。匹配的城市保存在一个列表中,列表是以国家为键的字典值({'FRA':['Paris']}) 目前,我主要使用for循环遍历地址和城市以

问题: 是否可以对两个数据帧/系列的字符串匹配进行矢量化

概念: 我有两个数据帧(df_地址,df_世界城市):

  • df_地址:包含一列地址数据(如“Sherlock Str;Paris;”)
  • df_world_city:包含一列城市名称和相应国家(“FRA”、“巴黎”)
  • 我浏览了每个地址,并试图与所有城市进行匹配,找出地址中提到的城市,并将相应的国家添加到地址中。匹配的城市保存在一个列表中,列表是以国家为键的字典值({'FRA':['Paris']})

    目前,我主要使用for循环遍历地址和城市以匹配它们。多处理(48个进程)和大量数据(df_地址:160000行;df_wordl_城市:2200000行)大约需要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
    
    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如果您有国家代码,为什么需要搜索城市,只需根据国家代码获取国家,而不管是哪个城市?其目的是从数据中获取国家和城市。有明确国家名称的地址我很容易就能得到。下一步是获取该地址的城市,因为我只匹配匹配国家的城市。当前函数的最后一步和思想是从数据中获取城市,并根据匹配的城市识别地址所在的国家,即使没有写出来。但假阳性点击的数量是极端的,结果是可用的。