Pandas DatetimeIndex от MongoDB ISODate
Мне сложно работать со временем / часовыми поясами. У меня есть исходные данные JSON формы
{ "Date": "28 Sep 2009 00:00:00", .... }
Эти данные затем загружаются в MongoDB, и это строковое представление даты преобразуется в объект JavaScript Date . Это преобразование в UTC приводит к следующей дате
- AttributeError: объект 'list' не имеет атрибута 'dtype'
- Объект 'module' не имеет атрибута '_strptime' с несколькими потоками Python
- Как добавить delta в python datetime.time?
- Дата проверки по дате в Python
- Как использовать время> год 2038 на официальном Windows Python 2.5
{ "_id": ObjectId("577a788f4439e17afd4e21f7"), "Date": ISODate("2009-09-27T23:00:00Z") }
Он «выглядит» так, как будто дата фактически была перемещена вперед в день, я предполагаю (возможно, неправильно), что это связано с тем, что моя машина настроена на ирландское стандартное время .
Затем я прочитал эти данные у MongoDB и использовал его для создания pandas DatetimeIndex
idx = pd.DatetimeIndex([x['Date'] for x in test_docs], freq='D')
который дает мне
что неверно, поскольку время не было правильно преобразовано с UTC на местное время. Поэтому я последовал за решением, данным в этом ответе
idx = pd.DatetimeIndex([x['Date'] for x in test_docs], freq='D') idx = idx.tz_localize(tz=tz.tzutc()) idx = idx.tz_convert(tz=tz.tzlocal()) frame = DataFrame(test_docs, index=idx) frame = frame.drop('Date', 1)
который дает мне правильный день назад
Затем я нормализую DatetimeIndex, поэтому часы удаляются, что позволяет мне группировать все записи в день.
frame.groupby(idx).sum()
На данный момент, однако, происходит что-то странное. Даты в конечном итоге группируются следующим образом
но это не отражает даты в кадре
Может ли кто-нибудь пролить свет на то, где я могу ошибиться?
Ответ на @ptrj
Явно использую мой часовой пояс в виде строки
idx = pd.DatetimeIndex([x['Date'] for x in test_docs], freq='D') idx = idx.tz_localize(tz=tz.tzutc()) idx = idx.tz_convert(tz='Europe/Dublin') idx = idx.normalize() frame = DataFrame(test_docs, index=idx) ... ... aggregate = frame.groupby(idx).sum() aggregate.plot()
это не работает для меня, это приводит к следующему графику
По какой-то причине groupby неправильно группируется в 2014 году, как показано ниже
Если вместо этого я использую
idx = idx.tz_convert(tz.gettz('Europe/Dublin'))
У меня такая же проблема
Преобразование в объект
idx = pd.DatetimeIndex([x['Date'] for x in test_docs], freq='D') idx = idx.tz_localize(tz=tz.tzutc()) idx = idx.tz_convert(tz=tz.tzlocal()) idx = idx.normalize() frame = DataFrame(test_docs, index=idx) aggregate = frame.groupby(idx.astype(object)).sum()
Этот подход, похоже, работает правильно для меня
- Даты и время в python: момент vs arrow vs delorean
- директива настраиваемого формата для python strptime
- Как получить объект tz_info, соответствующий текущему часовому поясу?
- Как библиотеки на разных языках программирования обрабатывают Date & Time, Timestamps & Durations, Leapseconds & -ears, DSTs & Timezones, ...?
- Ошибка structseq () с time.struct_time
2 Solutions collect form web for “Pandas DatetimeIndex от MongoDB ISODate”
Я смог воспроизвести ошибку со следующими данными:
idx0 = pd.date_range('2011-11-11', periods=4) idx1 = idx0.tz_localize(tz.tzutc()) idx2 = idx1.tz_convert(tz.tzlocal()) df = pd.DataFrame([1, 2, 3, 4]) df.groupby(idx2).sum() Out[20]: 0 1970-01-01 00:00:00-05:00 9 2011-11-10 19:00:00-05:00 1
Это ошибка в коде pandas, связанная исключительно с tz.tzlocal()
. Это проявляется также в:
idx2.tz_localize(None) Out[27]: DatetimeIndex(['2011-11-10 19:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00', '1970-01-01 00:00:00'], dtype='datetime64[ns]', freq='D')
Вы можете использовать любое из следующих решений:
-
используйте явно часовой пояс в виде строки:
idx2 = idx1.tz_convert(tz='Europe/Dublin') df.groupby(idx2).sum() Out[29]: 0 2011-11-11 00:00:00+00:00 1 2011-11-12 00:00:00+00:00 2 2011-11-13 00:00:00+00:00 3 2011-11-14 00:00:00+00:00 4
или если он не работает:
idx2 = idx1.tz_convert(tz.gettz('Europe/Dublin'))
-
преобразовать его в объект:
df.groupby(idx2.astype(object)).sum() Out[32]: 0 2011-11-10 19:00:00-05:00 1 2011-11-11 19:00:00-05:00 2 2011-11-12 19:00:00-05:00 3 2011-11-13 19:00:00-05:00 4
В принципе, нужно работать с чем-то еще, чем с DatetimeIndex с tz=tz.local()
.
EDIT: эта ошибка была исправлена только в pandas github. Исправление будет доступно в выпуске pandas 0.19.
Мне удалось обойти это сейчас, изменив мою groupby
на следующие
frame.groupby([pd.DatetimeIndex([x.date() for x in frame.index])]).sum()
поэтому, когда я изначально пытался groupby
idx = pd.DatetimeIndex([x['Date'] for x in test_docs], freq='D') idx = idx.tz_localize(tz=tz.tzutc()) idx = idx.tz_convert(tz=tz.tzlocal()) frame.groupby(idx).sum()
Теперь я groupby
метод date
для каждого элемента индекса перед выполнением операции groupby
.
Я отправляю это как ответ, если никто не отвечает, но я надеюсь, что кто-то ответит и объяснит, что происходит, так как мое «решение» кажется слишком хриплым для моих вкусов.
- Как узнать, есть ли данные, которые нужно читать из stdin в Windows на Python?
- Взаимодействие с кнопками / макросами внутри excel автоматически