numpy.longdouble数据类型引起的时间差错误

12

我有一个使用 numpy.longdouble 类型的时间,当我试图将这些值与 timedelta 函数一起使用时,会出现错误。但是,当我将其转换为 numpy.float64 类型时,一切都正常。有人可以解释一下这种行为吗?

import numpy as np
from datetime import timedelta
t1 = np.array([1000], dtype=np.longdouble)
t2 = np.array([1000], dtype=np.float64)

In [166]: timedelta(seconds=t1[0])
TypeError: unsupported type for timedelta seconds component: numpy.float64

In [167]: timedelta(seconds=t2[0])
Out[167]: datetime.timedelta(0, 1000)

In [168]: timedelta(seconds=t1[0].astype(np.float64))
Out[168]: datetime.timedelta(0, 1000)

当我试图查看变量的数据类型时,它们看起来类似但并不相同:

In [172]: t1[0].dtype
Out[172]: dtype('float64')

In [173]: t2[0].dtype
Out[173]: dtype('float64')

In [174]: np.longdouble == np.float64
Out[174]: False

In [175]: t1[0].dtype == t2[0].dtype
Out[175]: True

编辑

而且奇怪的是,它对于np.int32和np.int64也不起作用:

t3 = np.array([1000], dtype=np.int32)
t4 = np.array([1000], dtype=np.int64)

In [29]: timedelta(t3[0])
TypeError: unsupported type for timedelta days component: numpy.int32

In [69]: timedelta(t4[0])
TypeError: unsupported type for timedelta days component: numpy.int64

你可以在这里找到一些解释:https://dev59.com/ZHVC5IYBdhLWcg3w-WOs - MaTh
3个回答

8
所以,np.longdoubletimedelta 数据类型是没有实现的吗?
简而言之,是的。
根据文档

class datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])

所有参数都是可选的,默认为0。参数可以是整数、长整数或浮点数,并且可以为正数或负数。

这里的“长”指的是Python的long整数,而不是longdouble浮点数。
更新
我想我已经解决了看似不一致的 np.float64 的情况。 看起来与numpy数据类型是否子类化了timedelta接受的原生Python标量数据类型有关。
在我的 64 位机器上,运行 Python 2.7.9,numpy v1.10.1:
In [1]: timedelta(np.float64(1))
Out[1]: datetime.timedelta(1)

In [2]: timedelta(np.float32(1))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-4a7874ba393b> in <module>()
----> 1 timedelta(np.float32(1))

TypeError: unsupported type for timedelta days component: numpy.float32

In [3]: timedelta(np.int64(1))
Out[3]: datetime.timedelta(1)

In [4]: timedelta(np.int32(1))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-0475c6c8f1aa> in <module>()
----> 1 timedelta(np.int32(1))

TypeError: unsupported type for timedelta days component: numpy.int32

In [5]: issubclass(np.float64, float)
Out[5]: True

In [6]: issubclass(np.float32, float)
Out[6]: False

In [7]: issubclass(np.int64, int)
Out[7]: True

In [8]: issubclass(np.int32, int)
Out[8]: False

然而在评论中,OP报告说使用Python 3.4.3时timedelta(np.int64(1))无法正常工作。我认为这是因为当numpy在Python 3x上构建时,np.int64不再是int的子类

以下是Python 3.4.3中的情况:

In [1]: timedelta(np.int64(1))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-9902ea26a52d> in <module>()
----> 1 timedelta(np.int64(1))

TypeError: unsupported type for timedelta days component: numpy.int64

In [2]: issubclass(np.int64, int)
Out[2]: False

这真的很奇怪。我以为Python是跨平台的。你使用的numpy和Python版本是哪个?我的是:numpy: 1.10.1; Python 3.4.3 - Anton Protopopov
是的,看起来这就是Python3特有的行为。请参阅我的更新。 - ali_m

7
我遇到了一个类似的问题,其中timedelta(days = value.astype(int))无法工作,但是timedelta(days = int(value))可以正常工作。希望对未来的搜索者有所帮助。

1

在Anaconda64、Win7、Python 2.7.11、NumPy 1.10.1上,timedelta对numpy.int32的响应取决于其值:

In [3]: datetime.timedelta(seconds = numpy.int32(2147))
Out[3]: datetime.timedelta(0, 2147)

In [4]: datetime.timedelta(seconds = numpy.int32(2148))
Out[4]: datetime.timedelta(-1, 84253, 32704)

Spyder启动的完整日志:

Python 2.7.11 |Anaconda 2.1.0 (64-bit)| (default, Dec  7 2015, 14:10:42) [MSC v.1500 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.

IPython 4.0.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
%guiref   -> A brief reference about the graphical user interface.
In [1]: import numpy

In [2]: import datetime

In [3]: datetime.timedelta(seconds = numpy.int32(2147))

Out[3]: datetime.timedelta(0, 2147)

In [4]: datetime.timedelta(seconds = numpy.int32(2148))

Out[4]: datetime.timedelta(-1, 84253, 32704)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接