Python Numpy数组仅显示唯一的行

Python Numpy数组仅显示唯一的行,python,arrays,numpy,unique,Python,Arrays,Numpy,Unique,我希望数组中的行是唯一的。与numpy的unique函数相反,我想排除所有行,这些行会出现多次 因此,输入: [[1,1],[1,1],[1,2],[2,3],[3,4],[3,4]] 应导致输出 [[1,2],[2,3]]. 我试图用np.unique(array,return\u counts=True)计算每一行的外观,然后用>1过滤结果。我正在寻找一种更有效的方法来实现这一点,同时也在不返回计数的情况下做同样的事情,因为它们在numpy 1.9之前没有实现过 更新: 在我的例子中,数

我希望数组中的行是唯一的。与numpy的
unique
函数相反,我想排除所有行,这些行会出现多次

因此,输入:

[[1,1],[1,1],[1,2],[2,3],[3,4],[3,4]]
应导致输出

[[1,2],[2,3]].
我试图用
np.unique(array,return\u counts=True)
计算每一行的外观,然后用
>1
过滤结果。我正在寻找一种更有效的方法来实现这一点,同时也在不返回计数的情况下做同样的事情,因为它们在numpy 1.9之前没有实现过

更新: 在我的例子中,数据大小总是[m,2],但是一旦这个概念建立起来,它应该可以很容易地转移到[m,n]的例子中。在我的特殊情况下,数据集由整数组成,但解决方案不必局限于该假设。典型的数据集将采用
m~10^7
方法#1

这里有一种使用and的方法-

请注意,输出将不会保持输入数组中最初存在的元素顺序

方法#2

如果元素是整数,那么可以将2D数组
A
转换为1D数组,假设每一行都是索引元组,这应该是一个非常有效的解决方案。另外,请注意,这种方法将保持输出中元素的顺序。执行工作将是:-

# Convert 2D array A to a 1D array assuming each row as an indexing tuple
A_1D = A.dot(np.append(A.max(0)[::-1].cumprod()[::-1][1:],1))

# Get sorting indices for the 1D array
sort_idx = A_1D.argsort()

# Mask of start of each unique row in 1D sorted array 
mask = np.append(True,np.diff(A_1D[sort_idx])!=0)

# Get the counts of each unique 1D element
counts = np.bincount(mask.cumsum()-1)

# Select the IDs with counts==1 and thus the unique rows from A
out = A[sort_idx[np.nonzero(mask)[0][counts==1]]]
运行时测试和验证

功能-

def unq_rows_v1(A):
    sorted_idx = np.lexsort(A.T)
    sorted_Ar =  A[sorted_idx,:]
    mask = np.append(True,np.any(np.diff(sorted_Ar,axis=0),1))
    unq_count = np.bincount(mask.cumsum()-1) 
    return sorted_Ar[mask][np.nonzero(unq_count==1)[0]]

def unq_rows_v2(A):
    A_1D = A.dot(np.append(A.max(0)[::-1].cumprod()[::-1][1:],1))
    sort_idx = A_1D.argsort()
    mask = np.append(True,np.diff(A_1D[sort_idx])!=0)
    return A[sort_idx[np.nonzero(mask)[0][np.bincount(mask.cumsum()-1)==1]]]
计时和验证输出-

In [272]: A = np.random.randint(20,30,(10000,5))

In [273]: unq_rows_v1(A).shape
Out[273]: (9051, 5)

In [274]: unq_rows_v2(A).shape
Out[274]: (9051, 5)

In [275]: %timeit unq_rows_v1(A)
100 loops, best of 3: 5.07 ms per loop

In [276]: %timeit unq_rows_v2(A)
1000 loops, best of 3: 1.96 ms per loop
这个包(免责声明:我是它的作者)能够以完全矢量化的方式有效地解决这个问题。我还没有测试过numpy 1.9,如果它仍然相关的话,但也许你愿意给它一个旋转,让我知道。我没有任何理由相信它不会与旧版本的numpy一起工作

a = np.random.rand(10000, 3).round(2)
unique, count = npi.count(a)
print(unique[count == 1])

请注意,根据您最初的问题,此解决方案不限于特定的列数或数据类型。

输入数组的数据大小是多少?它们总是整数吗?请参阅计算行频率的答案,然后使用布尔索引。我认为这不会比这更有效,因为创建计数dict将是O(N)。您可以使用
集合。Counter
,如果您不想使用numpy,也应该这样做。这接近于的重复,但您还希望排除多次出现的所有行,而不是排除除一个重复之外的所有行。您的示例显示了一个具有形状(m,2)的数组,数组中的值是小整数。这是典型的数据吗?或者数组可能是n>2的(m,n),或者包含值上没有先验界限的整数,或者是浮点?
a = np.random.rand(10000, 3).round(2)
unique, count = npi.count(a)
print(unique[count == 1])