【问题标题】:Numpy: need a hand in understanding what happens with the "in" operatorNumpy:需要帮助理解“in”运算符会发生什么
【发布时间】:2018-01-13 16:58:43
【问题描述】:

如果有人能帮我解决这个问题(并解释发生了什么),我将不胜感激。

这行得通:

>>> from numpy import array
>>> a = array((2, 1))
>>> b = array((3, 3))
>>> l = [a, b]
>>> a in l
True

但这不是:

>>> c = array((2, 1))
>>> c in l
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

我想复制的行为是:

>>> x = (2, 1)
>>> y = (3, 3)
>>> l2 = [x, y]
>>> z = (2, 1)
>>> z in l2
True

请注意,上述内容也适用于可变对象:

>>> x = [2, 1]
>>> y = [3, 3]
>>> l2 = [x, y]
>>> z = [2, 1]
>>> z in l2
True

当然,知道:

>>> (a < b).all()
True

我尝试过(但失败了):

>>> (c in l).all()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

【问题讨论】:

    标签: python numpy python-2.7


    【解决方案1】:

    Python 选择 bool([False,True])True 因为(它说)任何非空列表都具有布尔值 True。

    Numpy 选择 bool(np.array([False, True])) 应该引发 ValueError。 Numpy 的设计观点是,一些用户可能想知道数组中的 any 元素是否为 True,而其他用户可能想知道 所有 元素是否为 True数组中为真。由于用户可能有相互冲突的愿望,NumPy 拒绝猜测。它会引发 ValueError 并建议使用 np.anynp.all(尽管如果希望复制类似 Python 的行为,您可以使用 len)。

    当您评估c in l 时,Python 会将cl 中以a 开头的每个元素进行比较。它评估bool(c==a)。我们得到bool(np.array([True True])),它引发了一个ValueError(出于上述原因)。

    既然 numpy 拒绝猜测,你必须要具体。我建议:

    import numpy as np
    a=np.array((2,1))
    b=np.array((3,3))
    c=np.array((2,1))
    l=[a,b]
    print(any(np.all(c==elt) for elt in l))
    # True
    

    【讨论】:

    • 非常有帮助,谢谢 (+1)...我仍然不明白为什么 a in l 得到的结果与 c in l 不同。在这两种情况下,命令都应该在标准列表中测试一个 numpy 数组......我看不到有什么区别?
    • @mac:这是一个很好的问题,但我不知道答案。 The docs say,“对于列表和元组类型,当且仅当存在索引 i 使得 x == y[i] 为真时 x in y 为真。”,但 bool(a==l[0]) 引发 ValueError 并且 @ 987654340@ 返回 True。我不知道如何解决这个(看似)矛盾。
    • list.__contains__() 首先检查身份,然后检查是否相等。所以 a in [a,b] 返回 True 只是因为第一项是 a。其他任何事情,即使是碰巧具有所有相同 a 值的不同数组对象也会评估相等比较,获取一个数组,然后在尝试将该数组转换为布尔值时得到一个异常。
    • @RobertKern:Oh, I see...非常感谢您的解释。
    • @RobertKern 谢谢。这说明了。我还发现this 很有趣,虽然不是我想要的答案。我正在选择现在接受的答案:尽管您分享了道德上的荣耀! :)
    猜你喜欢
    • 1970-01-01
    • 2020-10-19
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    相关资源
    最近更新 更多