如何从熊猫的地址中提取公寓

时间:2019-03-11 15:28:38

标签: python regex pandas

我有一个相当混乱的数据集,由于手动输入数据而导致许多不一致和错误。

我正在熊猫中处理此数据集的地址列。

我想做的是将地址栏分为3个单独的实体:

1)地址栏

2)街道编号列

3)一列公寓或单元号

数据如下:

address
----------------------
123 smith street #5234
5000 john ct
34 wood st apt# 23
523 fire road apt #87
charles way apt. 434
0987 misty lane unit B 

我已经将街道编号移到了自己的栏中。为此,我使用了一个简单的逻辑条件“ np.where”,即如果字符串以数字开头,则将其提取到新的街道列中。

我现在对如何使用公寓号码感到困惑。

我认为由于不一致,我必须执行以下操作:

df['apt/unit'] = np.where(str contains "apt", extract string starting at "apt" until end, else np.NaN)
df['apt/unit'] = np.where(str contains "unit", extract string starting at "unit" until end, else np.NaN)

我必须使用正则表达式来执行此操作吗?如果是这样,该怎么办?

这种思路是否有其他选择?

3 个答案:

答案 0 :(得分:2)

由于apt/unit列具有多个条件,因此您可以像下面这样使用np.select

# Define our conditions
conditions = [
    df.address.str.contains('apt'),
    df.address.str.contains('unit'),
    df.address.str.contains('#')
]

# Define our choices based on our conditions
choices = [
    df.address.apply(lambda x: x[x.find('apt'):]),
    df.address.apply(lambda x: x[x.find('unit'):]),
    df.address.apply(lambda x: x[x.find('#'):])
]

# Apply this logic by creating the new column and cleaning up address column
df['apt/unit'] = np.select(conditions, choices, default = '')

# Clean up our address column
choices2 = [
    df.address.apply(lambda x: x[:x.find('apt')]),
    df.address.apply(lambda x: x[:x.find('unit')]),
    df.address.apply(lambda x: x[:x.find('#')])
]
df['address'] = np.select(conditions, choices2, default = df.address)

输出

print(df)

             address  apt/unit
0  123 smith street      #5234
1       5000 john ct          
2        34 wood st    apt# 23
3     523 fire road    apt #87
4       charles way   apt. 434
5   0987 misty lane     unit B

答案 1 :(得分:1)

如果您想使用正则表达式,可以通过以下方法将数字,街道和公寓与单独的named groups匹配,然后使用df.apply填充数据框的新列。街道名称类型被列为蛮力。剩下的就是公寓号码。

regex = '(?P<num>\d+)? ?(?P<street>\w+ (street|way|st|road|ct|lane)) ?(?P<apt>.+)?'

def get_num(address):
    match = re.match(regex, address)
    return match.group('num')


def get_street(address):
    match = re.match(regex, address)
    return match.group('street')


def get_apt(address):
    match = re.match(address)
    return match.group('apt')


df['num'] = df['address'].apply(get_num)
df['street'] = df['address'].apply(get_street)
df['apt'] = df['address'].apply(get_apt)

答案 2 :(得分:0)

如果您已经删除了所有街道号码,则剩下的唯一号码应该是公寓号码。因此,您可以使用简单的正则表达式提取此列中剩余的所有数字:

df['apt_number'] = df.address.str.extract(r'([\d]+)')

编辑: 仅使用上面的答案,数字将保留在地址栏中,要删除该数字,我们只需将它们替换为空字符串即可:

df['address'] = df.address.str.replace(r'([\d]+)', '')