首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >熊猫DatetimeIndex MongoDB ISODate

熊猫DatetimeIndex MongoDB ISODate
EN

Stack Overflow用户
提问于 2016-07-05 10:57:04
回答 2查看 1.6K关注 0票数 7

我在时间/时区工作上遇到了一些困难。我有表单的原始JSON数据

代码语言:javascript
复制
{
  "Date": "28 Sep 2009 00:00:00",
  ....
}

然后将这些数据加载到MongoDB中,并将日期的字符串表示形式转换为JavaScript日期对象。此转换为UTC时间将导致以下日期

代码语言:javascript
复制
{
  "_id": ObjectId("577a788f4439e17afd4e21f7"),
  "Date": ISODate("2009-09-27T23:00:00Z")
}

它“看起来”似乎日期实际上已经提前了一天,我假设(可能是错误的)这是因为我的机器被设置为爱尔兰标准时间

然后,我从MongoDB中读取这些数据,并使用它创建一个熊猫DatetimeIndex

代码语言:javascript
复制
idx =  pd.DatetimeIndex([x['Date'] for x in test_docs], freq='D')

这给了我

这是不正确的,因为时间没有被正确地从UTC转换回本地时间。所以我遵循了这个答案中给出的解决方案

代码语言:javascript
复制
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以便移除时间,允许我在白天对所有条目进行分组。

代码语言:javascript
复制
frame.groupby(idx).sum()

然而,在这一点上,发生了一些奇怪的事情。这些日期最后按以下方式分组

但这并不能反映出框架中的日期

有人能说出我哪里可能出了问题吗?

回复@ptrj

显式地使用我的时区作为字符串

代码语言:javascript
复制
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年没有正确分组,如下所示

如果相反,我用

代码语言:javascript
复制
idx = idx.tz_convert(tz.gettz('Europe/Dublin'))

我也遇到了同样的问题

转换为对象

代码语言:javascript
复制
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()

这种方法对我来说似乎是正确的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-10 20:31:22

我能够用以下数据再现错误:

代码语言:javascript
复制
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

这是熊猫代码中的一个bug,只与tz.tzlocal()相关。它还体现在:

代码语言:javascript
复制
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=‘欧洲/都柏林’) df.groupby(idx2).sum() Out29: 0 2011年-11-11 00:00:00+00:00 1 2011年-11-12 00:00:00+00:00 2 2011-11 00:00:00+00:00 3 2011-11-14 00:00:00+00:00 4 或者如果它不起作用 idx2 =idx1.tz_convert(tz.gettz(“欧洲/都柏林”))
  • 将其转换为对象: df.groupby(idx2.astype(object)).sum() Out32: 0 2011-11-10 19:00:00-05:00 2011年-11:00 19:00-05:00 2 2011-12 19:00-05:00 3 2011-13 19:00:00-05:00

基本上,使用DatetimeIndex和tz=tz.local()转换为其他任何东西都是可行的。

编辑:这个错误刚刚被固定在熊猫github上。这一修正将在熊猫0.19版上发布。

票数 3
EN

Stack Overflow用户

发布于 2016-07-08 11:00:01

通过将groupby更改为下面的内容,我已经设法解决了这一问题

代码语言:javascript
复制
frame.groupby([pd.DatetimeIndex([x.date() for x in frame.index])]).sum()

所以我最初尝试groupby的地方

代码语言:javascript
复制
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()

在执行date操作之前,我现在对索引的每个元素调用groupby方法。

我把这作为一个答案,以防没有人回复,但我希望有人回答并解释正在发生的事情,因为我的“解决方案”似乎对我的口味来说太乏味了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38201666

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档