有条件的第一个数字后的分隔列

问题描述 投票:0回答:4

我有一个保存地址的数据框,该地址分为多列:

address        postalcode      city       province       country
-----------------------------------------------------------------
123 Fake St     F1A2K3       Fakeville      ON              CA

我想将地址栏分为两列,一栏用于门牌号码,一栏用于街道名称。因此,运行它之后,上面的df看起来像:

house_no    street        postalcode      city       province       country
----------------------------------------------------------------------------
  123       Fake St        F1A2K3       Fakeville      ON              CA

我一直通过简单地使用df[['house_no', 'street']] = df['address'].str.split(' ', 1, expand=True)来执行此操作,直到发现address列下的某些地址被构造为Apt 316 555 Fake Drive(或Unit 316 555 Fake Drive)为止,这种方法一直很好。因此,当我在这些上运行当前正在使用的内容时,我得到:

house_no          street        postalcode      city       province       country
---------------------------------------------------------------------------------
  Apt       316 555 Fake Drive     F1A2K3       Fakeville      ON           CA

显然,这不是我想要的。

所以本质上,我需要一种算法,将字符串分割成第一个数字,除非它以“ Unit”或“ Apt”开头,在这种情况下,它将采用它看到的第二个数字并将其分割为house_no柱。

我需要在不丢失任何信息的情况下执行此操作,因此也要保留单位/公寓号(可以存储在house_no列中,但理想情况下将拥有自己的unit_no列)。因此,理想情况下,输出如下所示:

unit_no    house_no   street    postalcode     city      province   country
---------------------------------------------------------------------------------
 Apt 316     555    Fake Drive    F1A2K3     Fakeville     ON         CA

鉴于原始的address列包含Apt 316 555 Fake Drive,现在被拆分为unit_nohouse_nostreet

我不确定从哪里开始,所以将不胜感激。

python pandas
4个回答
1
投票

让我们试试这个数据:

df = pd.DataFrame({'address':['123 Fake Street', 'Apt 316 555 Fake Drive']})

# df
#                   address
# 0         123 Fake Street
# 1  Apt 316 555 Fake Drive

由于您未指定是否要捕获Unit\Apt号码,因此我认为您不会:

df.address.str.extract('(?:Unit|Apt \d+ )?(?P<house_no>\d+) (?P<street>.*)$')

输出:

  house_no       street
0      123  Fake Street
1      555   Fake Drive

[如果要保留Unit/Apt,只需要稍加修改:

df.address.str.extract('(?P<unit_no>Unit|Apt \d+ )?(?P<house_no>\d+) (?P<street>.*)$')

输出:

    unit_no house_no       street
0       NaN      123  Fake Street
1  Apt 316       555   Fake Drive

0
投票

您可以使用df.loc功能,这应该可以工作。

df.loc[~df['address'].str.contains('Unit|Apt'), 'house_no'] = df['address'].str.split(' ')

0
投票

如果您始终有一个数字,后跟一个空格,然后是街道名称,则可以使用str.split('')对地址中数据的功能

例如,使用街道名称创建新列,使用街道编号创建新列

例如,创建两个数组,其中一个带有街道编号数字= address.split('')

数字[0]将始终是街道号

由于某些街​​道名称带有空格,请在数字后面附加数字[1:],这就是您的街道名称列数据

抱歉,请立即输入伪代码。


0
投票

我不确定我是否理解这个问题,但是如果您要消除单词Apt或Unit的话,就可以做到(这里df和df2是我制作的两个.xlsx文件,而df2只是具有所需列的另一个数据框,(house_no和street),并且行与df一样多,但具有空值):

import pandas as pd

df=pd.read_excel('raspuns_so.xlsx')

df2=pd.read_excel('sol.xlsx')
tmp=df['add'].str.split(' ', 1, expand=True)
for i, row_series in df2.iterrows():
    if tmp[0][i].isdigit():
        df2[['house_no', 'street']] = df['add'].str.split(' ', 1, expand=True)
    else:
        var=tmp[1][i].split(' ')
        arr=[var[0],var[1]]
        df2.at[i,'house_no'] = " ".join(arr)
        df2.at[i,'street'] = var[2]
print df2

我的df:

              address      pc       city province country
0         123 Fake ST  F1A2K3  Fakeville       ON      CA
1  Apt 123 555 FakeST  300000  Fakeville      OFF     USA

我的df2:

   house_no  street  pc  city  province  country
0         0       0   0     0         0        0
1         0       0   0     0         0        0

运行代码后的df2:

  house_no   street  pc  city  province  country
0      123  Fake ST   0     0         0        0
1  123 555   FakeST   0     0         0        0
© www.soinside.com 2019 - 2024. All rights reserved.