Как разделить строку адреса столбца с помощью регулярных выражений в пандах - PullRequest
0 голосов
/ 15 мая 2018

У меня есть следующий фрейм данных, который содержит address столбец,

df = pd.DataFrame(index=np.arange(10))
df["address"] = "Iso Omena 8 a 2"

нужно разделить его на другой столбец, чтобы результирующий кадр данных был похож на:

address          street_name  building_number door_number_letter appartment_numner
Iso Omena 8 a 2  Iso Omena    8                  a                2

чтохитрость заключается в том, что:

1. Имена могут иметь или не иметь пробелов между ними, как в примере выше.

2.door_number_letter иногда может быть числом, а не буквой.(например, "Iso Omena 8 5 2")

address Наиболее полная форма: [адрес, улица, номер здания, номер двери, номер_двери, номер квартиры_партии]

Ответы [ 4 ]

0 голосов
/ 15 мая 2018

Получив вдохновение от этого ответа, я придумал это решение с регулярным выражением + экстракт:

In [77]: df.address.iloc[1] = 'Big Apple 19 21 7'

In [78]: df.address.str.extract('(?P<street>^[^0-9]*) (?P<building>.+?) (?P<door>.+?) (?P<apartment>.+?$)')

Out[78]: 
  street building door apartment
0  Iso Omena        8    a         2
1  Big Apple       19   21         7    
2  Iso Omena        8    a         2
3  Iso Omena        8    a         2 
4  Iso Omena        8    a         2
5  Iso Omena        8    a         2
6  Iso Omena        8    a         2
7  Iso Omena        8    a         2
8  Iso Omena        8    a         2
9  Iso Omena        8    a         2
0 голосов
/ 15 мая 2018

Как то так?

import re

addr = "Iso Omena 8 a 2"

pattern = r'[a-öA-Ö]{3,100} *[a-öA-Ö]{3,100}'
street = re.findall(pattern, addr)[0]

bda = addr[len(street):].split()
print(street, bda,addr[len(street):])
0 голосов
/ 15 мая 2018

Вы можете использовать:

In [116]: s1 = df.address.str.findall(r'([\w ]+?) +(\d+) +([\d\w]+) +(\d+)').map(lambda s: s[0])

In [117]: s1
Out[117]: 
0    (Iso Omena, 8, a, 2)
1    (Iso Omena, 8, a, 2)
2    (Iso Omena, 8, a, 2)
3    (Iso Omena, 8, a, 2)
4    (Iso Omena, 8, a, 2)
5    (Iso Omena, 8, a, 2)
6    (Iso Omena, 8, a, 2)
7    (Iso Omena, 8, a, 2)
8    (Iso Omena, 8, a, 2)
9    (Iso Omena, 8, a, 2)
Name: address, dtype: object

Затем создайте фрейм данных на основе этих столбцов:

In [118]: pd.DataFrame(s1.values.tolist(), index=s1.index, columns=['street_name', 'building_number', 'door_number_letter', 'appartment_numner'])
Out[118]: 
  street_name building_number door_number_letter appartment_numner
0   Iso Omena               8                  a                 2
1   Iso Omena               8                  a                 2
2   Iso Omena               8                  a                 2
3   Iso Omena               8                  a                 2
4   Iso Omena               8                  a                 2
5   Iso Omena               8                  a                 2
6   Iso Omena               8                  a                 2
7   Iso Omena               8                  a                 2
8   Iso Omena               8                  a                 2
9   Iso Omena               8                  a                 2
0 голосов
/ 15 мая 2018

Предполагается, что адрес состоит только из букв и пробелов, а остальное разделено пробелами, а номер здания всегда начинается с числа , этого можно достичь следующим образом:

import re
s = ['Iso Omena 8 a 2', 'Xstreet 2', 'Isö Ømenå 8 a 2']
for addr in s:
    street = re.findall('[^\d]*', addr)[0].strip()
    rest = addr[len(street):].strip().split(' ')
    print(street, rest)

# Iso Omena ['8', 'a', '2']
# Xstreet ['2']
# Isö Ømenå ['8', 'a', '2']

Или, если вы хотите, чтобы все было в одном кадре данных:

df = pd.DataFrame()

df['address'] = ['Iso Omena 8 a 2', 'Xstreet 2', 'Asdf 7 c', 'Isö Ømenå 8 a 2']
df['street'] = None; df['building'] = None; df['door'] = None; df['appartment'] = None
import re
for i, s in enumerate(df['address']):
    street = re.findall('[^\d]*', s)[0].strip()
    df.loc[i,('street')] = street
    for col, val in zip(['building', 'door', 'appartment'], s[len(street):].strip().split(' ')):
        df.loc[i,(col)] = val

#            address     street building  door appartment
# 0  Iso Omena 8 a 2  Iso Omena        8     a          2     
# 1        Xstreet 2    Xstreet        2  None       None     
# 2         Asdf 7 c       Asdf        7     c       None    
# 3  Isö Ømenå 8 a 2  Isö Ømenå        8     a          2

РЕДАКТИРОВАТЬ: номер здания только слева от '-'sign:

вы можете просто заменить df.loc[i,(col)] = val на

df.loc[i,(col)] = re.findall('[^-]*', val)[0]

если это подходит также для двери и квартиры. В противном случае вам придется выполнить if-test против col == 'building', чтобы использовать только эту версию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...