Странное поведение pandas date_range

#python #pandas

#python #pandas

Вопрос:

date_range() Функция pandas демонстрирует странное поведение, когда часы между начальной и конечной датами не совпадают, а частота установлена на месяцы.

 >>> pd.date_range("2020-05-31 22:00:00", "2020-08-29 21:00:00", freq="1M")

DatetimeIndex(['2020-05-31 22:00:00', '2020-06-30 22:00:00'], dtype='datetime64[ns]', freq='M')
  

В этом примере я ожидал бы, что ‘2020-07-31 22:00:00’ будет присутствовать в индексе, но это не так.

Несмотря на то, что следующие примеры работают так, как ожидалось:

 >>> pd.date_range("2020-05-31 22:00:00", "2020-08-29 22:00:00", freq="1M")

DatetimeIndex(['2020-05-31 22:00:00', '2020-06-30 22:00:00',
               '2020-07-31 22:00:00'],
              dtype='datetime64[ns]', freq='M')

>>> pd.date_range("2020-05-31 22:00:00", "2020-08-29 23:00:00", freq="1M")

DatetimeIndex(['2020-05-31 22:00:00', '2020-06-30 22:00:00',
               '2020-07-31 22:00:00'],
              dtype='datetime64[ns]', freq='M')
  

Это также происходит, если предоставляются объекты Datetime, а не строки:

 >>> s = pd.to_datetime("2020-05-31 22:00:00", format="%Y-%m-%d %H:%M:%S")
>>> e = pd.to_datetime("2020-08-29 21:00:00", format="%Y-%m-%d %H:%M:%S")

>>> pd.date_range(s, e, freq="1M")
DatetimeIndex(['2020-05-31 22:00:00', '2020-06-30 22:00:00'], dtype='datetime64[ns]', freq='M')
  

Это ошибка или я чего-то не понимаю?

Pandas v1.1.0

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

1. похоже на ошибку. Я бы ожидал такого же поведения.

2. Это сложно. Я могу ответить немного, но 'M' это <MonthEnd> частота, которая не является фиксированной частотой .

Ответ №1:

То, что я обнаружил, — это использование времени меньше, чем указано в начальной дате, также не приведет к отображению последнего результата. вы можете использовать время, большее, чем начальная дата

 >>> pd.date_range("2020-05-31 22:00:00", "2020-08-29 23:00:00", freq="1M")

DatetimeIndex(['2020-05-31 22:00:00', '2020-06-30 22:00:00',
               '2020-07-31 22:00:00'],
              dtype='datetime64[ns]', freq='M')
  

или

Вместо использования «1M» в качестве значения для частоты вы можете использовать функцию pandas DateOffset, которая поможет вам получить желаемый результат.

 >>> pd.date_range("2020-05-31 22:00:00", "2020-08-29 21:00:00", freq=pd.DateOffset(months=1))

DatetimeIndex(['2020-05-31 22:00:00', '2020-06-30 22:00:00',
               '2020-07-30 22:00:00'],
              dtype='datetime64[ns]', freq='<DateOffset: months=1>')