【问题标题】:unexpected result when comparing numpy arrays with different shapes比较具有不同形状的 numpy 数组时的意外结果
【发布时间】:2015-04-06 15:19:11
【问题描述】:

当比较 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)

【问题讨论】:

    标签: python arrays numpy


    【解决方案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== 的其他Python 使用一致(.__eq__ 方法)。我不知道numpy 开发人员是否考虑过返回ValueError 的替代方案。

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

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

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

    __eq__ 的 Python 文档说:

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

    numpy 紧随其后 - 如果可能返回布尔数组,否则返回 False

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

    产生错误信息:

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

    这是一个常见的 SO 问题的根源。

    【讨论】:

    • 我在想,如果我想在无法广播时抛出 ValueError,我应该a - b == 0
    • 在测试生成整数数组的替代方法时,我确实使用了==。但是allclose 如果是浮点数会更好。 == aScalar 作为掩码也很常见。
    【解决方案2】:

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

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

    【讨论】:

    • "但是对于==,python 必须返回一个bool 对象" - 什么?为什么这么说?
    • 这是针对这种运算符的 Python 约定。看我的报价。
    • @user2357112 哎呀抱歉,这只是一个写作错误!谢谢提醒!
    猜你喜欢
    • 2019-11-11
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    相关资源
    最近更新 更多