Python 如何检查numpy数组列表是否包含给定的测试数组?

Python 如何检查numpy数组列表是否包含给定的测试数组?,python,numpy,Python,Numpy,我有一个numpy数组的列表 a = [np.random.rand(3, 3), np.random.rand(3, 3), np.random.rand(3, 3)] 我有一个测试阵列,比如说 b = np.random.rand(3, 3) 我想检查a是否包含b。然而 b in a 引发以下错误: ValueError:包含多个元素的数组的真值不明确。使用a.any()或a.all() 什么才是我想要的 好,所以中的不起作用,因为它有效地 def in_(obj, iterable

我有一个
numpy
数组的列表

a = [np.random.rand(3, 3), np.random.rand(3, 3), np.random.rand(3, 3)]
我有一个测试阵列,比如说

b = np.random.rand(3, 3)
我想检查
a
是否包含
b
。然而

b in a 
引发以下错误:

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


什么才是我想要的

好,所以中的
不起作用,因为它有效地

def in_(obj, iterable):
    for elem in iterable:
        if obj == elem:
            return True
    return False
现在的问题是,对于两个ndarray
a
b
a==b
是一个数组(试试看),而不是布尔值,因此如果a==b
失败,
。解决方法是定义一个新函数

def array_in(arr, list_of_arr):
     for elem in list_of_arr:
        if (arr == elem).all():
            return True
     return False

a = [np.arange(5)] * 3
b = np.ones(5)

array_in(b, a) # --> False

此错误是因为如果
a
b
numpy数组
,则
a==b
不会返回
True
False
,而是在比较
a
b
元素后返回
array
布尔值

您可以尝试以下方法:

np.any([np.all(a_s == b) for a_s in a])
  • [np.all(a_s==b)表示a中的a_s]
    这里,您正在创建
    布尔值列表,遍历
    a
    的元素,并检查
    b
    中的所有元素和
    a
    的特定元素是否相同

  • 使用
    np.any
    可以检查数组中的任何元素是否为
    True

如中所述,各州:

对于容器类型,如list、tuple、set、frozenset、dict或collections.deque,y中的表达式x等价于any(x是e或x==e表示y中的e)

a[0]==b
是一个数组,包含
a[0]
b
的元素级比较。这个数组的总真值显然不明确。如果所有元素都匹配,或者如果大多数元素都匹配,或者至少有一个元素匹配,那么它们是相同的吗?因此,
numpy
迫使你明确你的意思。您想知道的是,测试所有元素是否相同。您可以使用
numpy
的方法:

或者放入一个函数:

def numpy_in(arrayToTest, listOfArrays):
    return any((arrayToTest is e) or (arrayToTest == e).all()
               for e in listOfArrays)

您可以用
a
制作一个形状数组
(3,3,3)

a = np.asarray(a)
然后将其与
b
进行比较(我们在这里比较浮点数,因此应该使用
isclose()

例如:

a = [np.random.rand(3,3),np.random.rand(3,3),np.random.rand(3,3)]
a = np.asarray(a)
b = a[1, ...]       # set b to some value we know will yield True

np.all(np.isclose(a, b), axis=(1, 2))
# array([False,  True, False])

使用数组_等于numpy

    import numpy as np
    a = [np.random.rand(3,3),np.random.rand(3,3),np.random.rand(3,3)]
    b = np.random.rand(3,3)

    for i in a:
        if np.array_equal(b,i):
            print("yes")

正如@jotasi所强调的,由于数组中的元素比较,真值不明确。 这个问题以前有一个答案。总的来说,您的任务可以通过多种方式完成:

  • 要阵列的列表:
  • 通过将列表转换为(3,3,3)形状的数组,可以使用“in”运算符,如下所示:

        >>> a = [np.random.rand(3, 3), np.random.rand(3, 3), np.random.rand(3, 3)]
        >>> a= np.asarray(a)
        >>> b= a[1].copy()
        >>> b in a
        True
    
  • np.all:

    >>> any(np.all((b==a),axis=(1,2)))
    True
    
  • 列表扩展: 这可以通过迭代每个数组来完成:

    >>> any([(b == a_s).all() for a_s in a])
    True
    
  • 以下是上述三种方法的速度比较:


    你试过列表理解吗?列表理解是什么意思?在我的理解中,列表理解意味着类似于[a代表某个表中的a]在这个任务中列表理解的意义是什么?为什么不让
    a
    a
    3x3x3
    array?实际上,
    (a==b)。all()
    并不比
    np.array\u等于(a,b)
    。主要区别在于,
    np.array_equal
    首先测试数组的形状。
    >>> any(np.all((b==a),axis=(1,2)))
    True
    
    >>> any([(b == a_s).all() for a_s in a])
    True
    
    import numpy as np
    import perfplot
    
    perfplot.show(
        setup=lambda n: np.asarray([np.random.rand(3*3).reshape(3,3) for i in range(n)]),
        kernels=[
            lambda a: a[-1] in a,
            lambda a: any(np.all((a[-1]==a),axis=(1,2))),
            lambda a: any([(a[-1] == a_s).all() for a_s in a])
            ],
        labels=[
            'in', 'np.all', 'list_comperhension'
            ],
        n_range=[2**k for k in range(1,20)],
        xlabel='Array size',
        logx=True,
        logy=True,
        )