gpt4 book ai didi

python - 混合 pandas、datetime 和 numpy timedelta 时出现不稳定行为(bug?)

转载 作者:太空宇宙 更新时间:2023-11-03 15:08:47 25 4
gpt4 key购买 nike

我偶然注意到,日期时间上的一些操作 (a > b) 应该给出相同的(明确定义的)结果,但实际上给出了不同的结果(一些正确,一些错误,一些只是抛出错误),具体取决于我是否在 pandas 数据框或 numpy 中执行它们。我尝试在下面举一个小例子。为简洁起见,我使用 dateutile.parser.parse 函数,但我认为问题出现在 datetime、pandas 和 numpy 包之间的相互作用中,特别是在使用 pandas 的 DatetimeIndex 时。

首先,我尝试从 np.timedelta64 创建一个 df,但无法与单个 np.timedelta64 进行比较;这是一个明显的错误,我认为没关系:

import numpy as np
import pandas as pd
from dateutil.parser import parse
a1 = np.array([np.datetime64(parse('20200101')),np.datetime64(parse('20150101'))]).reshape((1,-1))
a2 = np.array([np.datetime64(parse('20100101')),np.datetime64(parse('20180101'))]).reshape((-1,1))
df1 = pd.DataFrame(a1-a2)
df1 > np.timedelta64(1000,'D')

上面的 df1 是:

    0                       1
0 3652 days 00:00:00 1826 days 00:00:00
1 730 days 00:00:00 -1096 days +00:00:00

第二个命令抛出错误“TypeError: ufunc 'isnan' 不支持输入类型,并且根据转换规则 ''safe'',无法将输入安全地强制为任何支持的类型”。到目前为止,一切顺利。

但是,如果我写:

a3 = pd.DatetimeIndex(a1.flatten()).values.reshape((1,-1))
df2 = pd.DataFrame(a3 - a2)

结果看起来类似:df2 =

    0           1
0 3652 days 1826 days
1 730 days -1096 days

但在这种情况下,df2 > np.timedelta64(1000,'D')不仅不会抛出错误,而且给出了错误的答案:

    0       1
0 True True
1 True False

另一方面,如果我们不执行 pd.DataFrame(a3-a2) > np.timedelta64(1000,'D'),而是执行 pd.DataFrame(a3- a2 > np.timedelta64(1000,'D')),我们得到了很好的答案:

    0       1
0 True True
1 False False

鉴于这种情况,我想某处一定存在错误,尽管我不太确定在哪里。也许我只是误解了一些符号,但无论如何,这种行为有点令人费解。一些问题可能来自这样的事实:根据上述定义,某些 dtype(例如 df1)以微秒为单位,其他一些(例如 df2)以纳秒为单位;但是,我希望这些应该得到正确处理,因为输出已正确转换为天......

作为引用,我使用的是 Python 3.5、numpy 版本 1.12.1、pandas 版本 0.18.0 和 python-dateutil 版本 2.5.1。

编辑:经过进一步测试,并考虑下面保罗的回答:

  • 该错误显然已在 Pandas 0.19.2 版本中得到解决。 Paul 下面的代码片段,以及上面关于 df2 的代码,都经过 Paul 的测试,可以在 Linux、Python3.5、Pandas 0.19.2 下正确工作,而且我还在 Linux 和 Windows 下检查过它们,都是 Python2.7和Python3.5、Pandas 0.20.2。

  • 在 0.18.2 中,Paul 下面的代码片段给出了与上面 df2 相同(错误)的答案。

  • 但是,在我的测试中,也是在 0.20.2 中,上面的第一个代码(此问题上的 df1)给出了错误的答案,全部为 False。这可能是因为 pandas 将日期存储为微秒(因为 Paul 的显式转换解决了问题),而 numpy 将日期存储为纳秒,因此存在一个静默因子 1000。不过,我认为应该注意这一点自动...

最佳答案

这种行为显然不一致,因为我无法在最新版本的 pandas 上重现您的问题,但两种情况之间的主要区别似乎是 df1 正在存储 np.dtype('timedelta64[us]') 对象,df2 正在存储 np.dtype('timedelta64[ns]' ) 对象。

我不确定为什么您认为 df1 > np.timedelta64(1000, 'D') 应该失败 - 我的直觉是它没有任何类型转换问题。也就是说,似乎至少从 0.19.2 版本开始,如果您始终确保将数据帧转换为 np.timedelta64[ns],您将不会'没有这个问题:

import pandas as pd
import numpy as np
from datetime import datetime

a1 = np.array([np.datetime64(datetime(2020, 1, 1)),
np.datetime64(datetime(2015, 1, 1))]).reshape((1,-1))
a2 = np.array([np.datetime64(datetime(2010,1,1)),
np.datetime64(datetime(2018,1,1))]).reshape((-1,1))

df1 = pd.DataFrame(a1 - a2).astype(np.dtype('timedelta64[ns]'))
kiloday = np.timedelta64(1000, 'D')

df1 > kiloday
# 0 1
# 0 True True
# 1 False False

关于python - 混合 pandas、datetime 和 numpy timedelta 时出现不稳定行为(bug?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44417961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com