考虑以下两个数组的列表:
from numpy import array
a = array([0, 1])
b = array([1, 0])
l = [a,b]
然后找到正确的索引给出
l.index(a)
>>> 0
虽然这对b不起作用:
l.index(b)
ValueError: The truth value of an array with more than one element is ambiguous.
Use a.any() or a.all()
在我看来,调用列表的.index函数不适用于numpy数组的列表.
有人知道解释吗?
到目前为止,我总是通过将数组转换为字符串来解决这个问题.有人知道更优雅,更快速的解决方案吗?
最佳答案 事实上,好的问题是l.index [a]如何返回正确的值.因为numpy数组以特殊方式处理相等性:l [1] == b通过比较各个值来返回数组而不是布尔值.这里它给出了数组([True,True],dtype = bool),它不能直接转换为布尔值,因此错误.
事实上,Python使用丰富的比较,特别是PyObject_RichCompareBool将搜索到的值与列表中的每个元素进行比较,这意味着它首先测试身份(a是b)和下一个等式(a == b).因此对于第一个元素,因为a是l [0],标识为真,并返回索引0.
但对于任何其他元素,与第一个元素的标识为false,并且相等性测试会导致错误. (感谢Ashwini Chaudhary对评论的好解释).
您可以通过测试包含与l [0]相同元素的数组的新副本来确认它:
d = array([0,1])
l.index(d)
它给出了相同的错误,因为标识是错误的,并且相等测试会引发错误.
这意味着您不能依赖任何使用比较的列表方法(index,in,remove),并且必须使用自定义函数,例如@orestiss提出的函数.或者,由于numpy数组列表似乎很难使用,你应该考虑包装数组:
>>> class NArray(object):
def __init__(self, arr):
self.arr = arr
def array(self):
return self.arr
def __eq__(self, other):
if (other.arr is self.arr):
return True
return (self.arr == other.arr).all()
def __ne__(self, other):
return not (self == other)
>>> a = array([0, 1])
>>> b = array([1, 0])
>>> l = [ NArray(a), NArray(b) ]
>>> l.index(NArray(a))
0
>>> l.index(NArray(b))
1