比较具有不同形状的numpy数组时出现意外结果

时间:2015-04-05 19:19:55

标签: python arrays numpy

当比较2个不同大小的numpy数组时,我会期望基于广播的布尔数组或引发错误。有时我只是得到False,好像把它们作为对象进行比较。

在下面我希望如果-失败,==也会失败:

In [18]: a = np.zeros((2,7,5))

In [19]: b = np.zeros((2,7))

In [20]: a == b
Out[20]: False

In [21]: a - b
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-21-a5f966a4b1f4> in <module>()
----> 1 a - b

ValueError: operands could not be broadcast together with shapes (2,7,5) (2,7)

2 个答案:

答案 0 :(得分:1)

数组上的算术运算符应用元素。创建一个新数组并用结果填充,如果数组没有相同的形状,python将引发一个ValueError来通知你这个问题,因为它是一个算术错误。

但是对于==,python会返回一个bool值,并且您可能希望将两个数组进行比较并获得bool值(即使它们的形状不同),所以首先检查shapes数组;如果它们不相同,则返回False

答案 1 :(得分:1)

a-b失败,因为自动广播发生在左侧,而不是右侧。

np.zeros((2,7,5))-np.zeros((2,7))[:,:,None]

作品

np.zeros((2,7,5))==np.zeros((2,7))[:,:,None]

并且相等测试逐个元素地工作。

但正如Kasra所指出的那样,在a==b中,逐元素比较将失败。显然这两个阵列并不相同。返回False==.__eq__方法)的其他Python使用一致。我不知道numpy开发人员是否考虑过返回ValueError的替代方案。

考虑比较字符串和列表时Python返回的内容:

'two'=='three'
[1,2,3]==[1]
'string'==['l','i','s','t']

我无法想到__eq__返回错误而不是False的情况。但是你可以用这种方式编写你自己的类。

__eq__的Python文档说:

  

如果没有实现给定参数对的操作,那么富比较方法可能会返回单例NotImplemented。按照惯例,返回False和True以进行成功比较。但是,这些方法可以返回任何值,因此如果在布尔上下文中使用比较运算符(例如,在if语句的条件下),Python将对值调用bool()以确定结果是true还是false

numpy跟随此 - 如果可能,返回一个布尔数组,否则返回False

bool(np.zeros((2,7,5))==np.zeros((2,7))[:,:,None])

生成错误消息:

  

ValueError:具有多个元素的数组的真值是不明确的。使用a.any()或a.all()

这是一个频繁的SO问题的根源。