Фільтрування фреймів даних Pandas за датами


157

У мене є DataFrame Pandas зі стовпцем "дата". Тепер мені потрібно відфільтрувати всі рядки в 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
Зараз цей виклик застарів!
Мохамед Тахер Альрефає

6
Що робити, якщо не хочеться фільтрувати за діапазоном дат, а за декількома датами?
Салем Бен Мабрук

53

Попередня відповідь, на моєму досвіді, не вірна, ви не можете передати її простим рядком, це повинен бути об'єктом дати. Так:

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

16
Я можу абсолютно пропустити рядок без проблем.
Ninjakannon


3
Панди перетворять будь-який рядок "datetime" в об'єкт datetime. Так це правильно
janscas

8
Я отримую таку помилку за допомогою цього: TypeError: '<' не підтримується між екземплярами 'int' та 'datetime.date'
Haris Khaliq,

41

І якщо ваші дати стандартизовані, імпортуючи пакет часу, ви можете просто скористатися:

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))].
Так S

20

Якщо ваш стовпець 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

Погляньте на документацію панд для DataFrame.query , зокрема згадку про локальний змінний @префікс розшифровки . У цьому випадку ми посилаємось, 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.