首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从numpy.datetime64到pandas.tslib.Timestamp bug的转换?

问从numpy.datetime64到pandas.tslib.Timestamp bug的转换?
EN

Stack Overflow用户
提问于 2013-02-04 20:44:55
回答 1查看 4.6K关注 0票数 3

我有一个python模块,它直接将数据加载到numpy.ndarray的一个片段中,以便在pandas.Dataframe中使用。然而,我注意到了'NA‘价值观的一个问题。我的文件格式表示NA值a s -9223372036854775808 (boost::integer_traits::const_min)。我的非NA值正按预期(带有正确值)加载到pandas.Dataframe中。我相信正在发生的事情是,我的模块加载到一个numpy.datetime64 ndarray中,然后将其转换为一个pandas.tslib.Timestamp列表。此转换似乎不保留“const_min”整数。尝试以下几点:

代码语言:javascript
复制
>>> pandas.tslib.Timestamp(-9223372036854775808)
NaT
>>> pandas.tslib.Timestamp(numpy.datetime64(-9223372036854775808))
<Timestamp: 1969-12-31 15:58:10.448384>

这是潘达斯的虫子吗?我认为在这种情况下,我可以让我的模块避免使用numpy.ndarray,并且使用Pandas没有碰到的东西(可能是预先分配了tslib.Timestamp本身的列表)。

下面是另一个意外发生的例子:

代码语言:javascript
复制
>>> npa = numpy.ndarray(1, dtype=numpy.datetime64)
>>> npa[0] = -9223372036854775808
>>> pandas.Series(npa)
0   NaT
>>> pandas.Series(npa)[0]
<Timestamp: 1969-12-31 15:58:10.448384>

以下是Jeff的评论,我有更多关于哪里出了问题的信息。

代码语言:javascript
复制
>>> npa = numpy.ndarray(2, dtype=numpy.int64)
>>> npa[0] = -9223372036854775808
>>> npa[1] = 1326834000090451
>>> npa
array([-9223372036854775808,     1326834000090451])
>>> s_npa = pandas.Series(npa, dtype='M8[us]')
>>> s_npa
0                          NaT
1   2012-01-17 21:00:00.090451

耶!这个系列保留了NA和我的时间戳。但是,如果我试图从该系列创建一个DataFrame,那么NaT就会消失。

代码语言:javascript
复制
>>> pandas.DataFrame({'ts':s_npa})
                      ts
0 1969-12-31 15:58:10.448384
1 2012-01-17 21:00:00.090451

嗯哼。一时兴起,我试着把我的整数解释成纳秒后的时代。令我惊讶的是,DataFrame运行正常:

代码语言:javascript
复制
s2_npa = pandas.Series(npa, dtype='M8[ns]')
>>> s2_npa
0                             NaT
1   1970-01-16 08:33:54.000090451
>>> pandas.DataFrame({"ts":s2_npa})
                             ts
0                           NaT
1 1970-01-16 08:33:54.000090451

当然,我的时间戳不对。我的观点是,pandas.DataFrame在这里的行为不一致。为什么它在使用dtype='M8ns‘时保留NaT,而在使用'M8us’时却不保存?

我目前正在使用这个解决方案来转换a,这会使事情慢很多,但是可以:

代码语言:javascript
复制
>>> s = pandas.Series([1000*ts if ts != -9223372036854775808 else ts for ts in npa], dtype='M8[ns]')
>>> pandas.DataFrame({'ts':s})
                          ts
0                        NaT
1 2012-01-17 21:00:00.090451

(几个小时后)

好吧我有进展了。我已经对代码进行了深入研究,以认识到Series上的repr函数最终调用了‘_format_datetime64 64’,它检查'isnull‘并打印出'NaT’,从而解释了两者之间的区别。

代码语言:javascript
复制
>>> pandas.Series(npa)
0   NaT
>>> pandas.Series(npa)[0]
<Timestamp: 1969-12-31 15:58:10.448384>

前者似乎是对NA的尊重,但它只在印刷时这样做。我想可能还有其他的熊猫函数叫做“isnull”,并根据答案采取行动,在这种情况下,这似乎部分地适用于NA时间戳。但是,我知道由于元素0的类型,系列是不正确的。它是一个时间戳,但应该是一个NaTType。我的下一步是深入到Series的构造函数中,找出熊猫在构建过程中何时/如何使用NaT值。当我指定dtype=‘m8us’.(未来还会有更多)。

按照安迪在评论中的建议,我试着用熊猫时间戳来解决这个问题。它没有起作用。以下是这些结果的一个例子:

代码语言:javascript
复制
>>> npa = numpy.ndarray(1, dtype='i8')
>>> npa[0] = -9223372036854775808
>>> npa
array([-9223372036854775808])
>>> pandas.tslib.Timestamp(npa.view('M8[ns]')[0]).value
-9223372036854775808
>>> pandas.tslib.Timestamp(npa.view('M8[us]')[0]).value
-28909551616000
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-06 18:03:22

答:否

从技术上讲,就是这样。我在github上发布了这个bug,并在这里得到了一个回复:https://github.com/pydata/pandas/issues/2800#issuecomment-13161074

现在在索引等方面不支持纳秒以外的单位。这应该严格执行

我和'ns‘而不是’我们‘一起运行的所有测试都很好。我期待着将来的发行。

对于感兴趣的人,我修改了我的C++ python模块,使其在我从磁盘加载的int64_t数组上进行迭代,并将所有内容乘以1000,除了NA值(boost::integer_traits::const_min)。我很担心演出,但是负载时间的差别对我来说很小。(在Python中做同样的事情非常非常慢。)

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

https://stackoverflow.com/questions/14695309

复制
相关文章

相似问题

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