Сопоставьте все, кроме сложного шаблона регулярного выражения, и замените его в Панд

#python #regex #pandas #regex-negation

Вопрос:

У меня есть сложный шаблон регулярных выражений для сопоставления смешанных дат для столбца csv в pandas df. Я хотел бы заменить все, кроме совпадения шаблона регулярного выражения, на «» . Я перепробовал почти все случаи отрицания (^ ?! и другие). Но я продолжаю заменять соответствие регулярному выражению на «» (пустая строка). Мой Код:

 import pandas as pd 
df.read_csv('path')
df=DataFrame(df)
df.columns=['Date'] 
Date=df.Date
df['Date']=df['Date'].str.replace(r'^((b(0?[1-9]|[12]d|30|31)[^wdrn:](0?[1-9]|1[0-2])[^wdrn:](d{4}|d{2})b)|(b(0?[1-9]|1[0-2])[^wdrn:](0?[1-9]|[12]d|30|31)[^wdrn:](d{4}|d{2})b))','')
 

Некоторые примеры моих данных:

 Date
21/04/2004
[N/F]
6/07/2004
{}
[N/F]
6/10/2004
16/06/2004
{}
21/06/2004
[N/F]
1/03/2018
23/03/17
{}
{}
4/04/2006
19/05/2006
"**3/04/2006/-2/06
2006**"
 

Ожидаемый Результат

 21/04/2004

6/07/2004


6/10/2004
16/06/2004

21/06/2004

1/03/2018
23/03/17


4/04/2006
19/05/2006
3/04/2006
 

Я был бы признателен вам за помощь. Большое спасибо.

Комментарии:

1. чему ты пытаешься соответствовать?

2. Я пытаюсь сопоставить все, кроме дат, а затем заменить их пустой строкой . Но отрицание работает не так, как я ожидал.

3. попробуйте указать дату, которой вы хотите соответствовать

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

5. ваше начальное регулярное выражение дает совпадение и не исключает [^d /d /d ] попробуйте это

Ответ №1:

Я немного упростил ваше регулярное выражение и извлекаю, а не заменяю:

Загрузка ваших данных в фрейм данных:

 import pandas as pd
import numpy as np

df = pd.read_csv('data.csv')
print(df)
 

Дает:

                          Date
0                  21/04/2004
1                       [N/F]
2                   6/07/2004
3                          {}
4                       [N/F]
5                   6/10/2004
6                  16/06/2004
7                          {}
8                  21/06/2004
9                       [N/F]
10                  1/03/2018
11                   23/03/17
12                         {}
13                         {}
14                  4/04/2006
15                 19/05/2006
16  **3/04/2006/-2/06n2006**
 

Теперь извлеките все, что можно разобрать как дату:

 pattern = r'(([1-9]|[12][0-9]|3[01])/(0[1-9]|1[012])/(20[01][0-9]|[0-9]{2}))'
df['extracted_date'] = df['Date'].astype(str).str.extract(pattern)[0]
df = df.fillna('')
print(df)
 

Который возвращает:

                          Date extracted_date
0                  21/04/2004     21/04/2004
1                       [N/F]               
2                   6/07/2004      6/07/2004
3                          {}               
4                       [N/F]               
5                   6/10/2004      6/10/2004
6                  16/06/2004     16/06/2004
7                          {}               
8                  21/06/2004     21/06/2004
9                       [N/F]               
10                  1/03/2018      1/03/2018
11                   23/03/17       23/03/17  
12                         {}               
13                         {}               
14                  4/04/2006      4/04/2006
15                 19/05/2006     19/05/2006
16  **3/04/2006/-2/06n2006**      3/04/2006
 

Комментарии:

1. хороший, просто понял, что вам нужно сохранить его в csv, чтобы прочитать образец. я думаю, вы могли бы просто скопировать код и использовать pd.read_clipboard (), и это сэкономило бы вам время на копирование и сохранение в файл csv