#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=
параметре:
- Использовать
pd.to_datetime(netnewprocess['AssessedDate'], format='%m/%d/%Y %I:%M:%S %p')
вместоnetnewprocess['AssessedDate']
, и - Использование
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)]