2014-08-27 213 views
3

我有一个nxn元素的布尔数组,如果有任何相同的行,我想检查是否有任何相同的行是相同的行相同。在numpy数组中找到相同的行和列

下面是一个例子:

A=np.array([[0, 1, 0, 0, 0, 1], 
      [0, 0, 0, 1, 0, 1], 
      [0, 1, 0, 0, 0, 1], 
      [1, 0, 1, 0, 1, 1], 
      [1, 1, 1, 0, 0, 0], 
      [0, 1, 0, 1, 0, 1]]) 

我想程序发现在第一和第三行是相同的,然后检查第一和第三列也是相同的;在这种情况下它们是。

+0

性能对你来说很重要吗? – wim 2014-08-27 17:04:46

+0

不是太多,因为阵列很小 – cgog 2014-08-27 17:07:02

回答

3

您可以使用np.array_equal()

for i in range(len(A)): #generate pairs 
    for j in range(i+1,len(A)): 
     if np.array_equal(A[i],A[j]): #compare rows 
      if np.array_equal(A[:,i],A[:,j]): #compare columns 
       print (i, j), 
     else: pass 

或使用combinations()

import itertools 

for pair in itertools.combinations(range(len(A)),2): 
    if np.array_equal(A[pair[0]],A[pair[1]]) and np.array_equal(A[:,pair[0]],A[:,pair[1]]): #compare columns 
     print pair 
1

既然你说性能不是关键的,这里是一个不是非常numpythonic蛮力解决方案:

>>> n = len(A) 
>>> for i1, row1 in enumerate(A): 
...  offset = i1 + 1 # skip rows already compared 
...  for i2, row2 in enumerate(A[offset:], start=offset): 
...   if (row1 == row2).all() and (A.T[i1] == A.T[i2]).all(): 
...    print i1, i2 
...    
0 2 

这可能是O(n^2)。我使用转置阵列A.T检查列也相等。

2

与典型的方式首发申请np.unique到二维数组,并使其返回唯一对:

def unique_pairs(arr): 
    uview = np.ascontiguousarray(arr).view(np.dtype((np.void, arr.dtype.itemsize * arr.shape[1]))) 
    uvals, uidx = np.unique(uview, return_inverse=True) 
    pos = np.where(np.bincount(uidx) == 2)[0] 

    pairs = [] 
    for p in pos: 
     pairs.append(np.where(uidx==p)[0]) 

    return np.array(pairs) 

然后,我们可以做到以下几点:

row_pairs = unique_pairs(A) 
col_pairs = unique_pairs(A.T) 

for pair in row_pairs: 
    if np.any(np.all(pair==col_pairs, axis=1)): 
     print pair 

>>> [0 2] 

当然有相当多的优化还有待做,但要点是使用np.unique。与其他方法相比,这种方法的效率在很大程度上取决于您如何定义“小”阵列。

相关问题