zss*_*zss 11 python numpy set-difference
我有两个大的二维数组,我想找到它们的集合差异,将它们的行作为元素.在Matlab中,这个代码就是setdiff(A,B,'rows').数组足够大,我想到的明显的循环方法需要花费太长时间.
jte*_*ace 10
这应该可行,但由于正在创建的视图的mergesort不可用,因此目前在1.6.1中已中断.它适用于1.7.0之前的版本.这应该是最快的方法,因为视图不必复制任何内存:
>>> import numpy as np
>>> a1 = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a2 = np.array([[4,5,6],[7,8,9],[1,1,1]])
>>> a1_rows = a1.view([('', a1.dtype)] * a1.shape[1])
>>> a2_rows = a2.view([('', a2.dtype)] * a2.shape[1])
>>> np.setdiff1d(a1_rows, a2_rows).view(a1.dtype).reshape(-1, a1.shape[1])
array([[1, 2, 3]])
Run Code Online (Sandbox Code Playgroud)
你可以用Python做到这一点,但它可能很慢:
>>> import numpy as np
>>> a1 = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> a2 = np.array([[4,5,6],[7,8,9],[1,1,1]])
>>> a1_rows = set(map(tuple, a1))
>>> a2_rows = set(map(tuple, a2))
>>> a1_rows.difference(a2_rows)
set([(1, 2, 3)])
Run Code Online (Sandbox Code Playgroud)
这是一个很好的替代纯numpy解决方案,适用于1.6.1.它确实创建了一个中间数组,因此这对您来说可能是也可能不是问题.它也不依赖于排序数组的任何加速(或setdiff可能).
from numpy import *
# Create some sample arrays
A =random.randint(0,5,(10,3))
B =random.randint(0,5,(10,3))
Run Code Online (Sandbox Code Playgroud)
举个例子,这就是我得到的 - 请注意,有一个共同的元素:
>>> A
array([[1, 0, 3],
[0, 4, 2],
[0, 3, 4],
[4, 4, 2],
[2, 0, 2],
[4, 0, 0],
[3, 2, 2],
[4, 2, 3],
[0, 2, 1],
[2, 0, 2]])
>>> B
array([[4, 1, 3],
[4, 3, 0],
[0, 3, 3],
[3, 0, 3],
[3, 4, 0],
[3, 2, 3],
[3, 1, 2],
[4, 1, 2],
[0, 4, 2],
[0, 0, 3]])
Run Code Online (Sandbox Code Playgroud)
我们寻找行之间的(L1)距离为零.这给了我们一个矩阵,在它为零的点上,这些是两个列表共有的项:
idx = where(abs((A[:,newaxis,:] - B)).sum(axis=2)==0)
Run Code Online (Sandbox Code Playgroud)
作为检查:
>>> A[idx[0]]
array([[0, 4, 2]])
>>> B[idx[1]]
array([[0, 4, 2]])
Run Code Online (Sandbox Code Playgroud)