Использование регулярных выражений для поиска данных в неправильном формате во фрейме данных pandas?

#python #pandas #dataframe

#python #pandas #фрейм данных

Вопрос:

Итак, у меня есть фрейм данных pandas со столбцом под названием «год», который содержит кучу лет. Столбец выглядит так:

 0     1885
1     1828
2     1913
3     1906
4     1963
5     1906
6     1906
7     1903
8     1969
9     1958
10    1695
11    1889
12    1906
13    1884
14    1890
15    1873
16    1908
17    1974
18    1961
19    1963
20    1973
21    2005
22    1970
23    1852
24    1906
  

Я пытаюсь использовать match (), чтобы найти год, который не в правильном формате. Даты должны содержать 4 цифры. Первым символом должен быть 1 или 2. Второй 0, 7, 8 или 9. Последние два символа должны быть цифрами. Предполагается выбрать 1695 год. Я также пытаюсь использовать функцию для приведения года в виде строки. Есть еще один столбец с именем ‘name’, и я пытаюсь напечатать имя, которое находится в той же строке, что и год (индекс 10).
Пока это мой код:

 y = re.match('^[3-9][1-6]*d', df['year']).group()
def string(y):
    return str(y)
string(y)
  

Любая помощь приветствуется, я новичок в регулярных выражениях и застрял на этом в течение нескольких часов. Спасибо.

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

1. ну 1695 , не соответствует вашему условию

Ответ №1:

Вы можете изменить свое регулярное выражение здесь и использовать метод pandas .str.match Series для его применения:

 # bad_date_mask is a boolean array,
#   where True means we have a "good" date, and False is a "bad" date
bad_date_mask = df["year"].astype(str).str.match("^[12][0789]dd$")

print(df.loc[bad_date_mask])
    year
10  1695
  

разбивка регулярных выражений:

  • ^ : Строка ДОЛЖНА начинаться с того, что идет после этого символа
  • [12] : Соответствует символам 1 или 2
  • [0789] : Соответствует символам 0, 7, 8, 9
  • d{2} : Соответствует любым 2 последовательным цифрам
  • $ : Строка должна заканчиваться сейчас. Не совпадать, если оно продолжается.

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

1. это выдает мне ошибку, потому что это не строковое значение в df, как бы вы порекомендовали это исправить?

2. Вам просто нужно принудительно преобразовать ваш dtype в str: df["year"].astype(str).str.match("^[12][0789]dd$") я также обновлю свой ответ

Ответ №2:

Мое предложение состояло бы в том, чтобы 1) разбить его и 2) не использовать регулярные выражения без необходимости. Давайте создадим логическую маску, а затем найдем строки, в которых выполняются все условия:

 # Dates should have 4 digits
cond1 = (df.year.str.len() == 4)

# The first character should be a 1 or 2
cond2 = df.year.str.get(0).isin(("1","2"))

# The second a 0, 7, 8 or 9
cond3 = df.year.str.get(1).isin(("0","7","8","9"))

# The last two characters should be digits
cond4 = df.year.str[-2:].str.isnumeric()


joint_cond = cond1 amp; cond2 amp; cond3 amp; cond4
solution = df[joint_cond]
  

Предложенный crieteria не вернет значение 1695