Как отфильтровать фрейм данных дат по определенному месяцу / дню?

#python #pandas #dataframe #rows

#python #панды #фрейм данных

Вопрос:

Итак, мой код выглядит следующим образом:

 df['Dates'][df['Dates'].index.month == 11]
  

Я проводил тест, чтобы узнать, смогу ли я отфильтровать месяцы, чтобы он показывал только даты ноября, но это не сработало. Это выдает следующую ошибку: AttributeError: объект ‘Int64Index’ не имеет атрибута ‘месяц’.

Если я сделаю

 print type(df['Dates'][0])
  

затем я получаю класс pandas.tslib.Timestamp’, что наводит меня на мысль, что типы объектов, хранящихся в фрейме данных, являются объектами Timestamp. (Я не уверен, откуда берется ‘Int64Index’ … для ошибки ранее)

Что я хочу сделать, так это следующее: столбец фрейма данных содержит даты начала 2000-х годов, представленные в следующем формате: дд / мм / гггг. Я хочу фильтровать только по датам с 15 ноября по 15 марта, независимо от ГОДА. Какой самый простой способ сделать это?

Спасибо.

Вот df[‘Dates’] (с индексами):

 0    2006-01-01
1    2006-01-02
2    2006-01-03
3    2006-01-04
4    2006-01-05
5    2006-01-06
6    2006-01-07
7    2006-01-08
8    2006-01-09
9    2006-01-10
10   2006-01-11
11   2006-01-12
12   2006-01-13
13   2006-01-14
14   2006-01-15
...
  

Комментарии:

1. Пожалуйста, покажите пример того, как df это выглядит. Вы, вероятно, хотите df.set_index('Dates') , но трудно сказать, не видя.

2. Отредактируйте свой вопрос df так, чтобы он был правильно отформатирован. Опубликуйте заголовок всего фрейма данных, если сможете.

Ответ №1:

Использование pd.to_datetime amp; dt accessor

Принятый ответ — это не способ «pandas» подойти к этой проблеме. Чтобы выбрать только строки с month 11 помощью, используйте средство dt доступа:

 # df['Date'] = pd.to_datetime(df['Date']) -- if column is not datetime yet
df = df[df['Date'].dt.month == 11]
  

То же самое работает для дней или лет, где вы можете заменить dt.month на dt.day или dt.year

Помимо этого, есть еще много других, вот несколько:

  • dt.quarter
  • dt.week
  • dt.weekday
  • dt.day_name
  • dt.is_month_end
  • dt.is_month_start
  • dt.is_year_end
  • dt.is_year_start

Полный список см. В Документации

Комментарии:

1. Этот подход не будет работать для старых дат, например OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 1031-11-29 00:00:00 . Для таких данных вам нужно использовать некоторую магию

Ответ №2:

Сопоставьте анонимную функцию для вычисления месяца с серией и сравните ее с 11 ноября. Это даст вам логическую маску. Затем вы можете использовать эту маску для фильтрации вашего фрейма данных.

 nov_mask = df['Dates'].map(lambda x: x.month) == 11
df[nov_mask]
  

Я не думаю, что есть прямой способ фильтровать так, как вы хотите, игнорируя год, поэтому попробуйте это.

 nov_mar_series = pd.Series(pd.date_range("2013-11-15", "2014-03-15"))
#create timestamp without year
nov_mar_no_year = nov_mar_series.map(lambda x: x.strftime("%m-%d"))
#add a yearless timestamp to the dataframe
df["no_year"] = df['Date'].map(lambda x: x.strftime("%m-%d"))
no_year_mask = df['no_year'].isin(nov_mar_no_year)
df[no_year_mask]
  

Комментарии:

1. На самом деле int64 был вызван тем, что сначала был получен доступ к индексу df['Dates'].index.month . В этом случае индекс был Int64Index, у которого нет атрибута month .

Ответ №3:

В вашем коде есть две проблемы. Во-первых, необходимо привести ссылку на столбец после условия фильтрации. Во-вторых, можно использовать «.month» со столбцом или индексом, но не с обоими. Должно работать одно из следующих действий:

 df[df.index.month == 11]['Dates']

df[df['Dates'].month == 11]['Dates']