2013-01-18 62 views
8

长时间读写器,第一次写入。不受支持的操作数类型为*:'numpy.ndarray'和'numpy.float64'

我搜索了谷歌和堆栈溢出,但没有真正能够找到这个问题的一般答案。

我在使用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

我知道随机函数和数字似乎很奇怪,但这个概念应该还是工作,因为它的工作当两个被设置成变量分别。

为什么会发生这种情况?我怎样才能解决它在一般意义上?

非常感谢! Jason

+0

我想你已经陷入了代码中的错误,你可能需要将其报告给numpy的人。为了记录,如果'a'是'np.ndarray','x'是'np.float64',那么'x * a'和'a * x [']'都可以工作,但是没有一个* x','a + x','a/x'或'a-x'。很难理解为什么,如果'a'的__mul__'方法不能处理它,''x'的__rmul__'不会被调用,因为它似乎知道如何处理这种情况... – Jaime

+0

非常感谢审查我的。我会尝试在numpy中报告它是一个问题。 您认为可能有办法解决这个问题吗? – Jason

+0

如果你用'x ['''替换''x''它可以工作,但它是一个讨厌的破解... – Jaime

回答

7

我怀疑这里的问题是NumPy无法在其数组中存储Python long值。只要您尝试这样做,它会将数组的数据类型切换为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的阵列。

解决方法是避免与NumPy阵列创建long值,并使用float!而非:

>>> 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对象?

+0

良好的通话!我的数组变量(y = np.square(np.add(np.divide(np.zeros(100),42),( - 27)** 40))如上面在我的问题中定义的)具有类型'object'( y.dtype) 不幸的是,我不确定我能否强制它成为一个浮动,考虑到它是从一个浮动开始的,并且沿着某个方向将自己抛到了一个很长的位置。 – Jason

+0

这是'(-27)** 40'的操作问题。 NumPy无法直接处理Python'long'。但是,您可以使用'np.array'将NumPy数组转换为另一个不同类型的数组。例如,'np.array(np.array(27 ** 40),dtype = np.float64)'将返回一个'float64'类型的数组。 –

+0

是的,我能够找到我的代码中生成的ints 27和40的位置,并将它们转换为浮点数。记录np.arange生成int32。大多数numpy函数都在浮点数中工作,包括np.ones和np.zeros – Jason

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

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

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

所以y*x计算结果为y.__mul__(x)并给出了预期的结果。相反,x*y第一次尝试为x.__mul__(y)(未实现,正常),而不是y.__rmul__(x)(未实现但存在错误)。如已经指出的,我们可以有任意对象的nd.arrays,并且一切都变得清晰。

编辑

此bug已被修正(可能在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 
+0

为什么会降低这个值? – Worthy7

+0

@ Worthy7不知道为什么我的回答是downvoted:恕我直言,它确定负责意想不到的行为的numpy错误,由https://github.com/numpy/numpy/issues/2930#issuecomment-12445232(和不,我在阅读了这个numpy问题后,我没有写出答案。) –

相关问题