Rik*_*son 5 python arrays comparison numpy vectorization
所有 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])
Run Code Online (Sandbox Code Playgroud)
我最终应该得到一个M.shape[0]^2大的真值表,其中至少对角线是正确的。
broadcasting将输入扩展为两个版本后的杠杆,4D以便我们可以比较成对数组块,同时保持最后两个轴对齐 -
result = (M[:,None] == M).all((2,3))\nRun Code Online (Sandbox Code Playgroud)\n\n我们可以使用最后两个轴作为输入将其扩展到通用的 n 维数组情况.all()-
(M[:,None] == M).all((-2,-1))\nRun Code Online (Sandbox Code Playgroud)\n\n杠杆作用views内存效率更高、性能更高的内存 -
# /sf/answers/3149930661/ @Divakar\ndef view1D(a): # a is array\n a = np.ascontiguousarray(a)\n void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))\n return a.view(void_dt).ravel()\n\nM1D = view1D(M.reshape(M.shape[0],-1))\nresult = M1D[:,None] == M1D\nRun Code Online (Sandbox Code Playgroud)\n\n大阵列上的计时 -
\n\nIn [48]: np.random.seed(0)\n ...: M = np.random.randint(0,10,(100,100,100))\n\nIn [49]: %timeit (M[:,None] == M).all((-2,-1))\n10 loops, best of 3: 92.2 ms per loop\n\nIn [50]: %%timeit \n ...: M1D = view1D(M.reshape(M.shape[0],-1))\n ...: M1D[:,None] == M1D\n1000 loops, best of 3: 627 \xc2\xb5s per loop\nRun Code Online (Sandbox Code Playgroud)\n\n原来的一个——
\n\nIn [54]: %%timeit\n ...: result = np.zeros((M.shape[0], M.shape[0]))\n ...: for i in range(M.shape[0]):\n ...: for j in range(M.shape[0]):\n ...: result[i,j] = numpy.array_equal(M[i], M[j])\n10 loops, best of 3: 125 ms per loop\nRun Code Online (Sandbox Code Playgroud)\n\n结论是 - 删除循环,但要注意内存使用情况。如果可能的话,找到其他方法来保持向量化和内存效率。
\n