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

Я хотел бы разбить строку на Pandas DataFrame столбцы, используя регулярное выражение.

Пример данных CSV [ Обновлено ]:

Data;Code;Temp;....
12 364 OPR 4 67474;;33;...
893 73 GDP hdj 747;;34;...
hr 777 hr9 GDP;;30;...
463 7g 448 OPR;;28;...

Желаемая ситуация: [ Обновлено ]

Data           | Code        | Temp     | ...
------------------------------------------------
12 364         | OPR 4 67474 | 33       | ...
893 73         | GDP hdj 747 | 34       | ...
hr 777 hr9 GDP | NaN         | 30       | ...
463 7g 448 OPR | NaN         | 28       | ...

regex:

code = re.compile('\sOPR.?[^$]|\sGDP.?[^$]')

Мне нужно разделить только если OPR или GDP не в конце строки.Я искал способ разделиться на основе позиции в матче.Что-то вроде: match.start())
Я пробовал что-то вроде: df['data'].str.contains(code, regex=True) и df['data'] = df['data'].str.extract(code, expand=True) и str.find, кажется, работает только со строкой, а не с re.Pattern.Я не делаю это.

Я довольно новичок в Пандах, поэтому, пожалуйста, потерпите меня.

Ответы [ 3 ]

0 голосов
/ 15 декабря 2018

Я довольно новичок в python, поэтому кто-то может прокомментировать, если это не очень хороший подход.Мое мышление состояло в том, чтобы взять ввод и обработать его построчно.отбросьте конечную точку с запятой, поскольку у вас ее нет в выводе.затем с помощью регулярных выражений разделите строку на пробел, только если за ней следует OPR или GDP, а не в конце строки.Если это дает только один элемент в списке, тогда добавьте список с NaN, чтобы заполнить второй столбец.затем я напечатал с форматированием.

import re
data_string="""12 364 OPR 4 67474;
893 73 GDP hdj 747;
hr 777 hr9 GDP;
463 7g 448 OPR;
"""

data_list=data_string.splitlines()
for data in data_list:
    data_split=re.split("\s(?=(?:GDP|OPR)[^$])",data[:-1])
    if len(data_split)==1: data_split.append("NaN")
    print("%-20s|%-20s" % tuple(data_split))

ВЫВОД

12 364              |OPR 4 67474         
893 73              |GDP hdj 747         
hr 777 hr9 GDP      |NaN                 
463 7g 448 OPR      |NaN                 

Обновлено в свете вопросов редактирования и комментариев

На основе вашего обновленияна вопрос и комментарии вы можете попробовать ниже.Я бы посоветовал вам проверить это и проверить наличие крайних случаев или добавить проверки или условные проверки перед выполнением обновлений.

import pandas as pd
import re

source_data = {'data': ['12 364 OPR 4 67474', '893 73 GDP hdj 747', 'hr 777 hr9 GDP','463 7g 448 OPR'],
         'code': [None, None, None, None],
         'Temp': [33,34,30,28]
         }
df = pd.DataFrame.from_dict(source_data)
print("Original df:")
print(df, "\n")

row_iter=df.iterrows()
for index,row in row_iter:
    data=df.at[index,'data']
    data_split=re.split("\s(?=(?:GDP|OPR)[^$])",data)
    if len(data_split)==2:
        df.at[index,'data']=data_split[0]
        df.at[index,'code']=data_split[1]

print("Updated df:")
print(df)

OUTPUT

Original df:
                 data  code  Temp
0  12 364 OPR 4 67474  None    33
1  893 73 GDP hdj 747  None    34
2      hr 777 hr9 GDP  None    30
3      463 7g 448 OPR  None    28 

Updated df:
             data         code  Temp
0          12 364  OPR 4 67474    33
1          893 73  GDP hdj 747    34
2  hr 777 hr9 GDP         None    30
3  463 7g 448 OPR         None    28
0 голосов
/ 15 декабря 2018

Допустим, это ваш фрейм данных,

    Data                Temp
0   12 364 OPR 4 67474  33
1   893 73 GDP hdj 747  34
2   hr 777 hr9 GDP      30
3   463 7g 448 OPR      28

Вы можете использовать извлечение с несколькими группами захвата на основе условия

df1[['Data', 'Code']] = df.loc[~df['Data'].str.endswith(('OPR','GDP')), 'Data'].str.extract('(.*)([A-Z]{3} .*)')
df2[['Data', 'Code']] = df.loc[df['Data'].str.endswith(('OPR','GDP')), 'Data'].str.extract('(.*[OPR|GDP]$)(.*)')
df[['Data', 'Code']] = pd.concat([df1,df2])

    Data            Temp    Code
0   12 364          33      OPR 4 67474
1   893 73          34      GDP hdj 747
2   hr 777 hr9 GDP  30  
3   463 7g 448 OPR  28  
0 голосов
/ 15 декабря 2018

Итак, сначала нужно проверить, есть ли в конце данные ВВП или ОРС.Если нет, то вы можете использовать сгруппированные регулярные выражения, чтобы получить нужные элементы.Здесь вещи в круглых скобках () представляют группу.Я назвал их, используя синтаксис? P, который является optinal.

import re

data = ["12 364 OPR 4 67474;",
   "893 73 GDP hdj 747;",
   "hr 777 hr9 GDP;",
   "463 7g 448 OPR;"]

for item in data:
# first check if it ends with GPR; or OPR;
if re.search("GDP;|OPR;$", item):
    # as u specified it needs to be ignored
    print(item)
else:
    # now u can split into two parts - i am splitting in three but u can do use them however u like
    splited_match_obj = re.search("(?P<Data>.+)(?P<Value>OPR|GDP)(?P<Code>.+)", item)
    print(splited_match_obj["Data"], splited_match_obj["Value"], splited_match_obj["Code"] )

enter image description here

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