Панды, столбец фильтра для > дата

#python #pandas

Вопрос:

я пытаюсь отфильтровать дату оценки столбца, например так:

netnewprocess = netnewprocess[(netnewprocess['AssessedDate'] > assessdateprev)]

мой assessdateprev = 8/31/2021 00:00

Фильтр, похоже, работает с большинством значений, но я все еще вижу элементы в столбце до 31 августа. Верхняя половина приведенных ниже результатов правильна, а нижней половины там быть не должно. Я могу что-нибудь сделать, чтобы это исправить?

 9       9/15/2020 1:40:27 PM
136     9/14/2020 4:07:19 PM
146     9/21/2020 4:28:59 PM
185     9/18/2020 2:20:15 PM
200      9/8/2020 9:59:22 AM
        
1687     8/6/2021 8:47:07 AM
1757     8/6/2021 4:59:01 PM
1785     8/5/2021 9:42:14 AM
1787     8/5/2021 9:40:51 AM
1810     8/6/2021 2:00:58 PM
 

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

1. проверьте тип данных вашего столбца df.dtypes , если в вашем столбце нет даты и времени или аналогичного типа dtype , особенно если это строка, может произойти ошибка

2. assessdataprev является str и AssessedDate является объектом.

3. Существует несколько различных способов справиться с этим. Вы пробовали строковые методы, чтобы сократить часть времени перед фильтрацией? т. е. выберите число n, чтобы df[date_colmn].apply(лямбда x: x[:n]) возвращал мм/дд/гггг, затем попробуйте отфильтровать что-либо до 31.08.2011.. Я постараюсь добавить правильный ответ, как только у меня будет больше времени, извините.

4. Если ваша первая половина выборочных данных относится к 2020 году, они вообще не должны отображаться в окончательном результате (поскольку они появились раньше 8/31/2021 00:00 ) . Я изменил все даты на 2021 год для тестирования в своем решении.

5. @SeaBean , извините, даже не понял этого. Вы правы.

Ответ №1:

Поскольку ваш столбец AssessedDate и константа assessdateprev имеют строковый тип, а не тип даты и времени, ваш существующий код фактически фильтруется путем сравнения строк и дает неправильный результат.

Это связано с тем , что строка 8/6/2021 8:47:07 AM при сравнении с другой строкой 8/31/2021 00:00 результат сравнения строк будет 8/6/2021 8:47:07 AM >> 8/31/2021 00:00 , так как при сравнении символа за символом » 6 «слева больше, чем «3» справа.

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

Вы можете использовать pd.to_datetime() с указанием правильной строки формата в format= параметре:

  1. Использовать pd.to_datetime(netnewprocess['AssessedDate'], format='%m/%d/%Y %I:%M:%S %p') вместо netnewprocess['AssessedDate'] , и
  2. Использование pd.to_datetime('8/31/2021 00:00', format='%m/%d/%Y %H:%M') вместо assessdateprev

чтобы изменить свой код на:

 netnewprocess = netnewprocess[(pd.to_datetime(netnewprocess['AssessedDate'], format='%m/%d/%Y %I:%M:%S %p') > pd.to_datetime('8/31/2021 00:00', format='%m/%d/%Y %H:%M'))]
 

Вы можете обнаружить, что приведенные выше коды также работают без указания строк формата. Тем не менее, у этого есть 2 преимущества: (1) избежать двусмысленности, будет ли 8/6/2021 это 6 августа или 8 июня; (2) возможно ускорить преобразование формата даты-времени, сэкономив внутреннее время обработки при определении фактического формата даты.

Результат:

(заменил ваши выборочные данные на все даты в 2021 году, вместо первой половины 2020 года)

 print(netnewprocess)

             AssessedDate
9    9/15/2021 1:40:27 PM
136  9/14/2021 4:07:19 PM
146  9/21/2021 4:28:59 PM
185  9/18/2021 2:20:15 PM
200   9/8/2021 9:59:22 AM
 

Или, что еще лучше, если вы можете изменить формат столбца и константы строки даты на формат даты и времени, вы можете использовать:

 # convert to datetime first
netnewprocess['AssessedDate'] = pd.to_datetime(netnewprocess['AssessedDate'], format='%m/%d/%Y %I:%M:%S %p')
assessdateprev = pd.to_datetime('8/31/2021 00:00', format='%m/%d/%Y %H:%M')

# Then, you can use your code
netnewprocess = netnewprocess[(netnewprocess['AssessedDate'] > assessdateprev)]