【问题标题】:How to extract string from dataframe after regex matching正则表达式匹配后如何从数据框中提取字符串
【发布时间】:2018-05-17 11:36:29
【问题描述】:

想要从 Pandas 数据框中的邮政编码后出现的地址中提取城市名称。 鉴于: 10 rue des Treuils BP 12 33023, Bordeaux France 我想从数据框列中提取Bordeaux

城市名称总是在逗号之后,但不保证是一个单词。需要去掉国家名称,这将是一个固定的字符串,如 France 、 Italy 等。

更多法国城市名称示例

  • Les Deux Alpes

  • 瓦尔迪泽

【问题讨论】:

  • 你能提供更具体的细节吗?例如,您可以假设城市名称始终是最后一个逗号之后的第一个单词吗?另外,到目前为止,您尝试过什么?正则表达式是要求还是偏好?
  • 你会如何处理“..., New York United States”?是否有所有国家名称的固定列表?
  • United States 将是固定字符串,可以像完全匹配一样被剥离?
  • 请在pastebin.com 中发布固定国家/地区列表并分享链接,以便我们进一步为您提供帮助。
  • 是的,请。正确锚定的正则表达式可能如下所示 (?<=\d{5}, ).*(?=France|United States)

标签: python regex pandas


【解决方案1】:

United States 将是固定的字符串,可以像 on 一样被剥离 完全匹配


我的解决方案是删除国家/地区名称,这将只留下城市名称
这种方法似乎更容易,因为国家名称是固定的,可以根据list 轻松删除,即:

  1. split()两个中的地址,基于逗号,);
  2. replace()国名与nothing
  3. 使用 panda 的 apply() 应用包含上述步骤的 get_city() 函数。
  4. 使用 panda 的 tolist() 将列 City 转换为列表。最后一步是可选的,因为它取决于您将如何处理城市名称。

即:

import pandas as pd
addresses = [['10 rue des Treuils BP 12 33023, Bordeaux France'],['Rua da Alegria 22, Lisboa Portugal'],['22 Some Street, NYC United States']]
df = pd.DataFrame(addresses,columns=['Address'])

countries = ['Portugal', 'France', 'United States']

def get_city(address):
    city_country = address.split(",")[1]
    for i in countries: city = city_country.replace(i, "")
    return city.strip()

df['City'] = df['Address'].apply(get_city)
print (df['City'].tolist())

输出

['Bordeaux', 'Lisboa', 'NYC']

PS: 您可能希望lower() 同时列出地址和国家/地区列表以避免大小写SenSitIve 不匹配。

【讨论】:

    【解决方案2】:

    如果我们认为您的正则表达式适用于法国地址(以法国结尾),那么您可以使用:

    /,\s([A-Z][A-Za-z\s-]+)\sFrance/gm
    

    Link to the online regex simulator where I tested the expression

    您之前提到了美国,但实际上地址的书写方式完全不同,所以我猜您必须为它制作另一个正则表达式。 (IE: 4十字巷 谢勒维尔,印第安纳州 46375)

    【讨论】:

      【解决方案3】:

      是的,也许一些高级正则表达式可以处理这个问题,但熊猫天真的方法是:

      import pandas as pd
      import numpy as np
      
      col = pd.Series(['10 rue des Treuils BP 12 33023, Bordeaux France',
                       '10 rue des Treuils BP 12 33023, Les Deux Alpes France',
                       '10 rue des Treuils BP 12 33023, New York United States'])
      
      cities = np.where(col.str.endswith('United States'), 
                        col.str.split(', ').str[1].str.split().str[:-2].str.join(' '), 
                        col.str.split(', ').str[1].str.split().str[:-1].str.join(' '))
      
      print(cities)
      #['Bordeaux' 'Les Deux Alpes' 'New York']
      

      更通用但不那么有效的解决方案(但谁需要速度对吧?)

      import pandas as pd
      
      col = pd.Series(['10 rue des Treuils BP 12 33023, Bordeaux France',
                       '10 rue des Treuils BP 12 33023, New York United States',
                       '10 rue des Treuils BP 12 33023, Seoul South Korea',
                       '10 rue des Treuils BP 12 33023, Brazzaville Republic of Congo'])
      
      countries = {'United States': 2 , 'South Korea': 2, 'Republic of Congo': 3}
      n = [next((countries[k] for k,v in countries.items() if i.endswith(k)), 1) for i in col]
      cities = [' '.join(i.split(', ')[1].split()[:-y]) for i,y in zip(col,n)]
      
      print(cities)
      # ['Bordeaux', 'Les Deux Alpes', 'New York', 'Seoul', 'Brazzaville']
      

      然后简单地赋值:

      df['city'] = cities
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-01
        相关资源
        最近更新 更多