Python Regex для разделения комментариев на датафреймы - PullRequest
3 голосов
/ 09 апреля 2020

У меня есть куча строк, которые пользователи вводили в различные комментарии, объединенные вместе. Иногда они вводили дату, если были комментарии в течение нескольких дней. Я пытаюсь найти способ разделить каждую дату и соответствующий комментарий. Текстовые комментарии могут выглядеть следующим образом:

raw_text = ['3/30: The dog is red. 4/01: The dog is blue', 'there is a green door', '3-25:Foobar baz'] 

Я хотел бы преобразовать этот текст в:

df = pd.DataFrame([[0,'3/30','The dog is red.'],[0,'4/01','The dog is blue'],[1,np.nan,'there is a green door'],[2,'3-25','Foobar baz']],columns = 'row_id','date','text')

print(df)

   row_id  date                   text
0       0  3/30        The dog is red.
1       0  4/01        The dog is blue
2       1   NaN  there is a green door
3       2  3-25             Foobar baz

Я думаю, что мне нужно сделать, это найти точки с запятой, а затем вернуться назад на первое число перед этой точкой с запятой, чтобы указать даты (иногда они используют / для разделения, а иногда -).

Буду признателен за любые идеи о том, как подойти к этому с помощью регулярных выражений - это выходит за рамки моих простых знаний по split / findall.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 10 апреля 2020

Я не очень хорошо знаю регулярные выражения (так что, возможно, будет лучшее решение), но, похоже, это работает ...

# sample list
raw_text = ['10-30: The dog is red. 4/01: The dog is blue', 'there is a green door',
            '3-25:Foobar baz', '11-25:Foobar baz. 12/20: something else']

# create regex (e.g., the variable 'n' in the comment below represents a number)
# if 'nn/nn' OR 'nn-nn' OR ' n-nn' OR ' n/nn' OR ' nn-nn' OR ' nn/nn' OR string starts with a number
regex = r'(?=\d\d/\d\d:)|(?=\d\d-\d\d:)|(?= \d-\d\d:)|(?= \d/\d\d:)|(?= \d\d-\d\d:)|(?= \d\d/\d\d:)|(?=^\d)'
# if string starts with alpha characters or there is a ':'
regex2 = r'(?=^\D)|:'

# create a Series by splitting on regex and explode
s = pd.DataFrame(raw_text)[0].str.split(regex).explode()
# boolean indexing to remove blanks
s2 = s[(s != '') & (s != ' ')]

# strip leading or trailing white space then split on regex2
df = s2.str.strip().str.split(regex2, expand=True).reset_index()
# rename columns
df.columns = ['row_id', 'date', 'text']


   row_id   date                         text
0       0  10-30   The dog is red until 5/15.
1       0   4/01              The dog is blue
2       1               there is a green door
3       2   3-25                   Foobar baz
4       3  11-25                  Foobar baz.
5       3  12/20               something else
0 голосов
/ 10 апреля 2020

Данные

df=pd.DataFrame({'raw_text':['3/30: The dog is red.', '4/01: The dog is blue', 'there is a green door', '3-25:Foobar baz']})
df

Создать столбец даты

df['date']=df.raw_text.str.extract(r"([\d+\/\-+\d+]+(?=\:))")
df

Создать текстовый столбец

df['text']=df.raw_text.str.extract(r"((?:-)?[^\s:][A-Za-z\s]+[^s])", expand=True)
df

Создать столбец с идентификатором строки соответствовать тексту 'The dog' и создать временный индекс столбца k = 'The dog'

dicto ={'The dog':0}
df['index']=df['raw_text'].str.extract('('+ k + ')', expand=False).map(dicto)
df

Ввод row_id с использованием index column

df['row_id']=df['index'].isna().astype('int64')

маскирует строки с текстом 'The dog' и автоматически добавляет цифры к остальным строкам

    m=df['row_id']!=0
    df.loc[m,'row_id']=np.arange(start=1, stop=3,step=1)# please note the stop may need to be increased if df is longer
df.drop(columns=['index'], inplace=True)

Выходные данные

enter image description here

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