将单行地址拆分为其组成部分?我在想reg-ex,但我不确定?

时间:2018-02-09 18:33:13

标签: python regex string pandas

我有一个大约8000行的.csv。在这个csv中,其中一个字段是一行邮寄地址。我想将这个单行邮寄地址拆分为其组成部分(街道地址,城市,州,邮政编码)。这就是我的csv或多或少的样子:

Name| Full Address | Street | City | State | PostalCode

Mary| 123 Yor Street Apt 5 Los Angeles California 12345 |Null | Null| Null | Null |
Bob | 567 Other Ave Chicago Illinois 56789              | Null | Null | Null | Null|
Jim | 890 Last Street COlorado Springs Colorado 80919   | Null | Null | Null | Null|

这就是我所拥有的。我正在寻找的是这个输出:

Name     Full Address                                    Street                City          State       PostalCode
Mary | 123 Yor Street Apt 5 Los Angeles California 12345 | 123 Yor Street Apt 5| Los Angeles| California| 12345|
Bob  | 567 Other Ave Chicago Illinois 56789              | 567 Other Ave    | Chicago | Illinois | 56789|
Jim  | 890 Last Street COlorado Springs Colorado 80919   | 890 Last Street | Colorado SPrings | Colorado | 80919

注意:我希望能够分开的最重要的部分是城市,所以如果街道名称的变化(如包括公寓#) s)复杂的事情,如果我能够成功提取城市,就可以忽略这些事情。

我没有很多使用字符串的经验,所以我有点从第一个开始。我的第一个想法是正则表达式可能能够解析它,但我不确定如何构造一个正则表达式来识别这些东西。因此,我不确定这是正确的做法。

没有逗号或类似的东西会产生明显的分隔符,这是另一个复杂的部分。也许在word.split()字段上使用Full Address,然后使用isin()和状态列的状态字典?

所以,任何能提供指导的人都会非常感激!

感谢您的时间。

PS - 我为表格格式道歉。

2 个答案:

答案 0 :(得分:3)

我觉得尝试使用正确的方法来解决这个问题会很困难。地址数据通常只是凌乱或糟糕。我发现模块usaddress非常有帮助。它不是100%,而是地址匹配是什么?

https://github.com/datamade/usaddress

以下是一个例子:

import usaddress

def main():
    address_list = [
    "123 main street",
    "99 elm st, manchester, nh",
    "56 magic dr, town of, bedford, nh",
    "123 Main St. Suite 100 IL, Faketown",
    ]

    for addr in address_list:
        data = usaddress.tag(addr)
        if "PlaceName" in data[0].keys():
            print(data[0]["PlaceName"])
        else:
            print("no city/town")

main()

结果是:

no city/town
manchester
town of, bedford
no city/town

除了PlaceName之外,你还可以将它带回来,例如:

    AddressNumber
    StreetName
    StreetNamePostType
    StreetAddress
    StateNmae
    OccupancyType
    OccupancyIdentifier

答案 1 :(得分:1)

正则表达式可能不会帮助你。一种解决方案是提取邮政编码,然后进行API调用以获取城市和州。有了这个,你可以事后扣除哪个部分是街道地址而不是。 (https://ziptasticapi.com/显然有一个非常简单的API。)

原型可能如下:

import pandas as pd
import requests
import json

df = pd.read_csv('path to file')

# extract zips
df['zip'] = df['Full Address'].apply(lambda x: x[-5:])

# function to get city and state
def get_city_state(zip):
    url = 'http://ziptasticapi.com/{}'.format(zip)
    response = requests.get(url)
    adress_info = json.loads(response.content)
    return adress_info['state'], adress_info['city']

# add state_city as tuple to your df
df['state_city'] = df['zip'].apply(lambda x: get_city_state(x))

# split tuple into city and state
df[['state', 'city']] = df['state_city'].apply(pd.Series)

API调用需要一些时间。所以实际上我认为更好的解决方案是提取所有唯一的拉链,然后将api响应存储在dict或其他内容中。