Фильтрация данных по фреймам Pandas по датам


157

У меня есть Pandas DataFrame со столбцом «дата». Теперь мне нужно отфильтровать все строки в DataFrame с датами за пределами следующих двух месяцев. По сути, мне нужно только сохранить строки, которые находятся в течение следующих двух месяцев.

Каков наилучший способ достичь этого?

Ответы:


238

Если столбец даты является индексом , используйте .loc для индексирования на основе меток или .iloc для позиционной индексации.

Например:

df.loc['2014-01-01':'2014-02-01']

Подробности смотрите здесь http://pandas.pydata.org/pandas-docs/stable/dsintro.html#indexing-selection

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

  1. Сделайте это индексом (временно или постоянно, если это данные временного ряда)
  2. df[(df['date'] > '2013-01-01') & (df['date'] < '2013-02-01')]

Смотрите здесь для общего объяснения

Примечание: .ix устарела.


4
Спасибо, прочитаю. Дата - это отдельный столбец, а не индекс в моем случае. Я должен был, вероятно, дать эту информацию в первую очередь. Мой вопрос был не очень информативным.
— AMM

42
Вы также можете использовать queryздесь. df.query('20130101 < date < 20130201'),
— Филип Клауд

10
Следует отметить, что фильтры для индекса (через .locи .ix) и столбцов в ваших примерах не эквивалентны. df.ix['2014-01-01':'2014-02-01']включает в себя, 2014-02-01пока df[(df['date'] > '2013-01-01') & (df['date'] < '2013-02-01')]не включает 2013-02-01, он будет соответствовать только строки до 2013-01-31.
— Рафаэль Барбоза

4
Этот вызов устарел сейчас!
— Мохамед Тахер Alrefaie

6
Что делать, если вы не хотите фильтровать по диапазону дат, но по нескольким временам?
— Салем Бен Мабрук

53

Предыдущий ответ, по моему опыту, неверен, вы не можете передать его простой строкой, он должен быть объектом datetime. Так:

import datetime 
df.loc[datetime.date(year=2014,month=1,day=1):datetime.date(year=2014,month=2,day=1)]

16
Я могу передать строку без проблем.
— Ниндзяканнон


3
pandas преобразует любую строку «datetime» в объект datetime ... так что это правильно
— janscas

8
Я получаю следующую ошибку, используя это: TypeError: «<» не поддерживается между экземплярами «int» и «datetime.date»
— Харис Халик

41

И если ваши даты стандартизированы путем импорта пакета datetime, вы можете просто использовать:

df[(df['date']>datetime.date(2016,1,1)) & (df['date']<datetime.date(2016,3,1))]  

Для стандартизации вашей строки даты с использованием пакета datetime вы можете использовать эту функцию:

import datetime
datetime.datetime.strptime

5
Рекомендуется использовать df[(df['date']>pd.Timestamp(2016,1,1)) & (df['date']<pd.Timestamp(2016,3,1))].
— Так с

20

Если ваш столбец datetime имеет тип datetime Pandas (например datetime64[ns]), для правильной фильтрации вам необходим объект pd.Timestamp , например:

from datetime import date

import pandas as pd

value_to_check = pd.Timestamp(date.today().year, 1, 1)
filter_mask = df['date_column'] < value_to_check
filtered_df = df[filter_mask]


7

Вы можете использовать pd.Timestamp для выполнения запроса и локальной ссылки

import pandas as pd
import numpy as np

df = pd.DataFrame()
ts = pd.Timestamp

df['date'] = np.array(np.arange(10) + datetime.now().timestamp(), dtype='M8[s]')

print(df)
print(df.query('date > @ts("20190515T071320")')

с выходом

                 date
0 2019-05-15 07:13:16
1 2019-05-15 07:13:17
2 2019-05-15 07:13:18
3 2019-05-15 07:13:19
4 2019-05-15 07:13:20
5 2019-05-15 07:13:21
6 2019-05-15 07:13:22
7 2019-05-15 07:13:23
8 2019-05-15 07:13:24
9 2019-05-15 07:13:25


                 date
5 2019-05-15 07:13:21
6 2019-05-15 07:13:22
7 2019-05-15 07:13:23
8 2019-05-15 07:13:24
9 2019-05-15 07:13:25

Взгляните на документацию pandas для DataFrame.query , в частности упоминание о префиксе udsing , на который ссылается локальная переменная @. В этом случае мы ссылаемся, pd.Timestampиспользуя локальный псевдоним, tsчтобы иметь возможность предоставить строку метки времени


Не могли бы вы передать ссылку на документацию по функциям @ts?
— Глен Мутри

6

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

Если вы просто хотите показать данные за два месяца с января по февраль, например, с 2020-01-01 по 2020-02-29, вы можете сделать это:

import pandas as pd
mydata = pd.read_csv('mydata.csv',index_col='date') # or its index number, e.g. index_col=[0]
mydata['2020-01-01':'2020-02-29'] # will pull all the columns
#if just need one column, e.g. Cost, can be done:
mydata['2020-01-01':'2020-02-29','Cost'] 

Это было проверено, работая на Python 3.7. Надеюсь, вы найдете это полезным.


1
index_colдолжен быть stringне список. mydata = pd.read_csv('mydata.csv',index_col='date')
— Шарл Шериф

5

Как насчет использования pyjanitor

У него есть интересные функции.

После pip install pyjanitor

import janitor

df_filtered = df.filter_date(your_date_column_name, start_date, end_date)

2

Кратчайший способ фильтрации вашего фрейма данных по дате. Предположим, что ваш столбец даты имеет тип datetime64 [ns]

# filter by single day
df = df[df['date'].dt.strftime('%Y-%m-%d') == '2014-01-01']

# filter by single month
df = df[df['date'].dt.strftime('%Y-%m') == '2014-01']

# filter by single year
df = df[df['date'].dt.strftime('%Y') == '2014']

1

Мне пока не разрешено писать комментарии, поэтому я напишу ответ, если кто-нибудь прочтет все из них и достигнет этого.

Если индекс набора данных представляет собой дату и время, и вы хотите отфильтровать это только по (например) месяцам, вы можете сделать следующее:

df.loc[df.index.month = 3]

Это отфильтрует набор данных для вас к марту.


1

Если вы уже преобразовали строку в формат даты, используя pd.to_datetime, вы можете просто использовать:

df = df[(df['Date']> "2018-01-01") & (df['Date']< "2019-07-01")]


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.