使用numpy数组进行原地操作时产生的TypeError错误?

24

如果我运行以下代码:

import numpy as np

b = np.zeros(1)
c = np.zeros(1)
c = c/2**63

print b, c
b += c

我收到了以下错误消息:

TypeError: ufunc 'add' output (typecode 'O') could not be coerced to provided
output parameter (typecode 'd') according to the casting rule ''same_kind''
如果我将 b += c 改为 b = b + c,代码就可以正常运行。为什么会这样呢?我在 RHEL 上运行 Python 2.7.2。
NumPy 版本:2.0.0.dev-a2a9dfb
GCC 版本:4.1.2 20080704(Red Hat 4.1.2-52)
提前感谢您的回答。

2
请发布您的numpy版本(print np.version.version)和您的gcc --version(从shell中),因为我们需要这些信息来进行错误报告。 - Pierre GM
1
我也遇到了/=的问题。感谢您的帖子解决了它。 - Charles Clayton
1个回答

22
当您执行c=c/2**63时,c会被转换为dtype=object(这是问题所在),而b则保持为dtype=float
dtype=object数组添加到dtype=float中,结果是dtype=object数组。可以将其视为dtype优先级,就像将numpy float添加到numpy int会得到numpy float一样。
如果您尝试在原地将object加到float中,则会失败,因为无法从object转换为float。但是,如果您使用b=b+c等基本加法,结果b将转换为dtype=object
请注意,使用c=c/2.**63c保持为float,并且b+=c可以正常工作。请注意,如果cnp.ones(1),那么您也不会有问题。
总之:(np.array([0], dtype=float)/2**63)).dtype == np.dtype(object)很可能是一个错误。

我不确定这是否是一个错误。也许是--但是2 ** 63int64的最大值要大,因此我不确定numpy除了将其存储在Python对象数组中之外还有其他做法。 - senderle
除了longfloat的优先级低之外。 - Pierre GM
是的,我也无法重现原帖作者的问题。 - senderle
@senderle 有趣:你使用的numpy版本是哪个? - Pierre GM
numpy 1.5.1。但是,我仍然遇到这个问题:>>>(np.array([1], dtype=np.float) / np.array([2 ** 63])) => array([1.08420217249e-19], dtype=object)。所以我现在非常不确定发生了什么。 - senderle
似乎我的 numpy 版本返回一个由 object 组成的数组,但在原地赋值时会悄悄地将结果强制转换为 float 数组。(想一想,这也是我所期望的。)我认为 OP 的行为与新的类型转换功能有关,该功能在 1.6 和 1.7 版本中添加(可能还有更高版本)。 - senderle

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