Фильтрация данных по фреймам 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.