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

157

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

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

AMM
источник

Ответы:

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 устарела.

Retozi
источник
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)]
oRange1
источник
16
Я могу передать строку без проблем.
Ниндзяканнон
9
Индекс
Ник
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
shm2008
источник
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]
VMAtm
источник
14

Если даты в индексе, то просто:

df['20160101':'20160301']
fantabolous
источник
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чтобы иметь возможность предоставить строку метки времени

danielhrisca
источник
Не могли бы вы передать ссылку на документацию по функциям @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)
pakira79
источник
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]

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

uhetz
источник
1

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

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

Джерин Мэтью
источник
0

Вы можете просто выбрать временной диапазон, выполнив: df.loc ['start_date': 'end_date']

Эрнесто Лопес Фуне
источник