8

长期阅读,第一次写。

我在谷歌和堆栈溢出上四处搜索,但并没有真正找到这个问题的一般答案。

我在使用 numpy 1.6.2 的 python 2.7.3 中收到“*: 'numpy.ndarray' 和 'numpy.float64' 不支持的操作数类型”错误。

该错误来自将 numpy 数组和 numpy 浮点数相乘,但并非每次都发生。

例如:

x = np.tan(1) # numpy.float64
y = np.array([0,1,2,3]) # numpy.ndarray
np.multiply(x,y) # works no problem

或者

x = np.tan(np.abs(np.multiply(-31,41)))  # numpy.float64
y = np.square(np.add(np.divide(np.zeros(100),42),(-27)**40)) # numpy.ndarray
np.multiply(x,y) # works no problem

两者都工作

现在对于有问题的孩子:

np.multiply(np.square(np.add(np.divide(np.zeros(100),42),-27)**40)),
np.tan(np.abs(np.multiply(-31,41))))

或者,x 定义如上:

np.multiply(np.square(np.add(np.divide(np.zeros(100),42),(-27)**40)),x)

两者都会产生错误:NotImplemented

我知道随机函数和数字看起来很奇怪,但从概念上讲这仍然应该工作,因为当两者都单独设置为变量时它工作。

为什么会这样?我该如何从一般意义上解决它?

非常感谢!杰森

4

2 回答 2

7

我怀疑这里的问题是 NumPy 无法long在其数组中存储 Python 值。一旦您尝试执行此操作,它会将数组的数据类型切换为object. 然后对数组的算术运算变得更加棘手,因为 NumPy 不能再自己进行算术运算。

>>> np.array(27**40)
array(1797010299914431210413179829509605039731475627537851106401L, dtype=object)
>>> np.array(27**40) * np.tan(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'numpy.ndarray' and 'numpy.float64'

奇怪的是,有时可以交换参数的顺序:

>>> np.tan(1) * np.array(27**40)
2.7986777223711575e+57

在第二种情况下,结果的类型是 Python float,而不是 NumPy 数组。

解决方法是避免long在 NumPy 数组中创建值,并使用floats 代替:

>>> np.array(27.0**40)
array(1.797010299914431e+57)
>>> np.array(27.0**40) * np.tan(1)
2.7986777223711575e+57
>>> np.multiply(np.square(np.add(np.divide(np.zeros(10),42),(-27.0)**40)),np.tan(1))
array([  5.02925269e+114,   5.02925269e+114,   5.02925269e+114,
         5.02925269e+114,   5.02925269e+114,   5.02925269e+114,
         5.02925269e+114,   5.02925269e+114,   5.02925269e+114,
         5.02925269e+114])

如果您确实收到这样的错误是未来,首先要做的是检查dtype被相乘的数组。它是否包含 NumPy 值或 Python 对象?

于 2013-01-18T22:32:16.410 回答
1

这是测验吗?我不明白为什么这个问题如此模糊......一切都归结为这个简单的事实。

给定

>>> x = 10**100
>>> type(x)
<type 'long'>
>>> y = np.float64(1)

我们有

>>> y.__mul__(x)
1e+100
>>> y.__rmul__(x)
NotImplemented

这是错误(或功能,我不知道)因为它应该是y.__mul__(x) == y.__rmul__(x)(至少对于x和的这些特定值y)。

Pythonlong不知道如何处理乘法numpy.float64(但这是正确的。)

>>> x.__mul__(y)
NotImplemented
>>> x.__rmul__(y)
NotImplemented

所以y*x评估y.__mul__(x)并给出预期的结果。相反x*y,首先尝试 as x.__mul__(y)(not implementation, OK) 比 as y.__rmul__(x)(not implemented but a bug.)。

正如已经指出的,我们可以拥有nd.arrays任意对象,一切都变得清晰起来。

编辑

此错误已得到纠正(可能在 numpy 版本 1.7 中):

>>> np.version.version
'1.13.1'
>>> x = 10**100
>>> y = np.float64(1)
>>> x.__mul__(y)
NotImplemented
>>> x.__rmul__(y)
NotImplemented
>>> y.__mul__(x)
1e+100
>>> y.__rmul__(x)
1e+100
>>> x*y
1e+100
>>> y*x
1e+100
于 2013-01-18T22:59:36.217 回答