![](/img/trans.png)
[英]Compare two 3d Numpy array and return unmatched values with index and later recreate them without loop
[英]Compare array wise of two 3D matrices in Numpy without for loops
所有Numpy专家,这对你们来说可能非常简单。 这个问题应该存在,但我没有找到解决问题的方法。 类似的是将NumPy和Numpy比较数组中的 两个矩阵逐行 比较到多个标量同时但不完全相同。
我需要为多维数组计算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.