Переформатировать дату внутри строки с помощью панд заменить на регулярное выражение

1

У меня есть столбец строк, как показано ниже, которые содержат информацию о дате, и мне нужно добавить ведущие нули в однозначные месяцы и дни. Я столкнулся с некоторыми проблемами, пытаясь сделать это чисто с pandas.DataFrame.replace и регулярными выражениями.

import pandas as pd
df = pd.DataFrame({'Key':['0123456789_1/2/2019','0123456789_11/23/2019','0145892367_10/2/2019','0145892367_4/13/2019']})

df
Out[323]: 
                     Key
0    0123456789_1/2/2019
1  0123456789_11/23/2019
2   0145892367_10/2/2019
3   0145892367_4/13/2019

Для приведенного выше столбца вывод, который я хотел бы получить после переформатирования, был бы следующим:

                     Key
0  0123456789_01/02/2019
1  0123456789_11/23/2019
2  0145892367_10/02/2019
3  0145892367_04/13/2019

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

r = df['Key'].str.split('_|/', expand=True)
df2 = r[0] + '_' + r[1].str.zfill(2) + '/' + r[2].str.zfill(2) + '/' + r[3]

df2
Out[333]: 
0    0123456789_01/02/2019
1    0123456789_11/23/2019
2    0145892367_10/02/2019
3    0145892367_04/13/2019
dtype: object

... Но когда я первоначально пытался сделать это с помощью pandas.DataFrame.replace, самым близким, что я смог получить, было:

df2 = df.replace(r'(_|/)([1-9]/)',r'\1 0\2',regex=True)

df2
Out[335]: 
                      Key
0   0123456789_ 01/2/2019
1   0123456789_11/23/2019
2  0145892367_10/ 02/2019
3  0145892367_ 04/13/2019

Есть две проблемы с этим, о которых я хотел бы узнать больше:

  1. В таких случаях, как строка 0, где месяц и день являются однозначными, он находит только месяц. Как я могу заставить это соответствовать обоим?
  2. Я не хочу пробелов, но когда я пытаюсь заменить с помощью r'\10\2', конечно, я получаю ошибку, потому что он думает, что я пытаюсь заменить в группе 10, и нет такой группы в первое регулярное выражение Если я попробую r'(\1)0\2', это сработает, за исключением того, что печатает буквальные скобки. Почему он это делает, и как я могу правильно написать это так, чтобы он печатал группу 1 сразу после буквального нуля?

Редактировать для пояснения: я знаю, что я мог бы также исправить это, анализируя даты, но я особенно заинтересован в решении регулярных выражений, в качестве учебного упражнения. Кроме того, потому что одна replace намного быстрее для больших фреймов данных.

Теги:
pandas
dataframe

2 ответа

2

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

df.Key=df.Key.str.split("_").str[0]+"_"+pd.to_datetime(df.Key.str.split("_")
            .str[1]).dt.strftime('%m/%d/%Y')
print(df)

                     Key
0  0123456789_01/02/2019
1  0123456789_11/23/2019
2  0145892367_10/02/2019
3  0145892367_04/13/2019
  • 1
    Это работает, но я пытаюсь понять, как обойти конкретные проблемы, с которыми я столкнулся, с помощью регулярных выражений. Я хотел бы иметь возможность использовать решение регулярных выражений для других случаев в будущем, которые могут не включать даты.
1

используя модуль datetime

df['Key'] = df.Key.str.split('_').apply(lambda x: x[0]+'_'+datetime.strptime(x[1], "%m/%d/%Y").strftime("%m/%d/%Y"))

Выход

                     Key
0  0123456789_01/02/2019
1  0123456789_11/23/2019
2  0145892367_10/02/2019
3  0145892367_04/13/2019
  • 0
    Спасибо, но я пытаюсь понять, как обойти конкретные проблемы, с которыми я столкнулся, с помощью регулярных выражений. Я хотел бы иметь возможность использовать решение регулярных выражений для других случаев в будущем.
  • 0
    использование datetime или pd.to_datetime, например @ anky_91, лучше, насколько я понимаю, оно охватывает все случаи, так как оно понимает даты, но регулярное выражение - нет, в некоторых случаях может произойти сбой

Ещё вопросы

Сообщество Overcoder
Наверх
Меню