numpy.longdouble dtype 的 timedelta 错误

timedelta error with numpy.longdouble dtype

我有时会使用 dtype 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

So maybe timedelta for dtype np.longdouble isn't implemented?

简而言之,是的。

来自 the documentation:

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

All arguments are optional and default to 0. Arguments may be ints, longs, or floats, and may be positive or negative.

这里 "long" 指的是 Python long 整数,而不是 longdouble 浮点数。


更新

我想我已经理解了 np.float64 看似不一致的行为。 似乎相关的是 numpy dtype 是否子类化 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 在评论中报告说 timedelta(np.int64(1)) 没有 使用 Python 3.4.3。我认为这是由于 when numpy is built on Python 3x, np.int64 no longer subclasses 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

在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)

我 运行 遇到了类似的问题

timedelta(days = value.astype(int)) 没用但是

timedelta(days = int(value)) 成功了。

我希望它对未来的 Google 员工有用。