繁体   English   中英

比较Numpy中两个3D矩阵的数组,而不是for循环

[英]Compare array wise of two 3D matrices in Numpy without for loops

所有Numpy专家,这对你们来说可能非常简单。 这个问题应该存在,但我没有找到解决问题的方法。 类似的是将NumPyNumpy比较数组中的 两个矩阵逐行 比较到多个标量同时但不完全相同。

我需要为多维数组计算numpy.array_equal ,但我很确定我不需要使用双重for循环。 但是,如果我使用双重for循环计算,它将如下所示:

M = numpy.array(
     [
         [
            [1,2,3],
            [1,3,4]
         ],
         [
            [3,4,5],
            [1,2,3]
         ],
         [
            [1,2,3],
            [1,3,4]
         ]
     ])

result = np.zeros((M.shape[0], M.shape[0]))
for i in range(M.shape[0]):
    for j in range(M.shape[0]):
        result[i,j] = numpy.array_equal(M[i], M[j])

我应该得到一个M.shape[0]^2大真值表,其中至少对角线是真的。

扩展后利用broadcasting - 输入到两个4D版本,这样我们就可以沿第一轴比较成对阵列块 ,同时保持最后两个轴对齐 -

result = (M[:,None] == M).all((2,3))

我们可以使用最后两个轴作为.all()输入,将其扩展为通用n-dim数组的情况 -

(M[:,None] == M).all((-2,-1))

利用views可以获得更高的内存效率,从而提高性能 -

# https://stackoverflow.com/a/44999009/ @Divakar
def view1D(a): # a is array
    a = np.ascontiguousarray(a)
    void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
    return a.view(void_dt).ravel()

M1D = view1D(M.reshape(M.shape[0],-1))
result = M1D[:,None] == M1D

大阵列上的时间 -

In [48]: np.random.seed(0)
    ...: M = np.random.randint(0,10,(100,100,100))

In [49]: %timeit (M[:,None] == M).all((-2,-1))
10 loops, best of 3: 92.2 ms per loop

In [50]: %%timeit 
    ...: M1D = view1D(M.reshape(M.shape[0],-1))
    ...: M1D[:,None] == M1D
1000 loops, best of 3: 627 µs per loop

原创 -

In [54]: %%timeit
    ...: result = np.zeros((M.shape[0], M.shape[0]))
    ...: for i in range(M.shape[0]):
    ...:     for j in range(M.shape[0]):
    ...:         result[i,j] = numpy.array_equal(M[i], M[j])
10 loops, best of 3: 125 ms per loop

结论是 - 删除循环,但要注意内存使用情况。 如果可能的话,找到其他方法来保持矢量化和内存效率。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM