我需要在numpy.array中找到唯一的行。

例如:

>>> a # I have
array([[1, 1, 1, 0, 0, 0],
       [0, 1, 1, 1, 0, 0],
       [0, 1, 1, 1, 0, 0],
       [1, 1, 1, 0, 0, 0],
       [1, 1, 1, 1, 1, 0]])
>>> new_a # I want to get to
array([[1, 1, 1, 0, 0, 0],
       [0, 1, 1, 1, 0, 0],
       [1, 1, 1, 1, 1, 0]])

我知道我可以创建一个集和循环数组,但我正在寻找一个有效的纯numpy解决方案。我相信有一种方法可以将数据类型设置为void,然后我可以使用numpy。唯一的,但我不知道如何让它工作。


当前回答

numpy_indexed包(免责声明:我是它的作者)将Jaime发布的解决方案包装在一个漂亮且经过测试的界面中,加上更多的特性:

import numpy_indexed as npi
new_a = npi.unique(a)  # unique elements over axis=0 (rows) by default

其他回答

除了@Jaime出色的回答,另一种折叠一行的方法是使用a.strides[0](假设a是c -毗连的),它等于a.dtype.itemsize* a.c nshape[0]。此外,void(n)是dtype((void,n))的快捷方式。我们最终得到了这个最短的版本:

a[unique(a.view(void(a.strides[0])),1)[1]]

For

[[0 1 1 1 0 0]
 [1 1 1 0 0 0]
 [1 1 1 1 1 0]]

最直接的解决方案是通过使行成为字符串,使行成为单个项。然后可以使用numpy将每一行作为一个整体进行比较,以确定其唯一性。这个解决方案是可推广的,你只需要重塑和转置你的数组为其他组合。以下是所提供的问题的解决方案。

import numpy as np

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

uniques, index = np.unique([str(i) for i in original], return_index=True)
cleaned = original[index]
print(cleaned)    

将:

 array([[0, 1, 1, 1, 0, 0],
        [1, 1, 1, 0, 0, 0],
        [1, 1, 1, 1, 1, 0]])

把我的诺贝尔奖寄出去

np。给出一个元组列表的唯一作品:

>>> np.unique([(1, 1), (2, 2), (3, 3), (4, 4), (2, 2)])
Out[9]: 
array([[1, 1],
       [2, 2],
       [3, 3],
       [4, 4]])

对于列表列表,它会引发TypeError: unhashable type: 'list'

import numpy as np
original = np.array([[1, 1, 1, 0, 0, 0],
                     [0, 1, 1, 1, 0, 0],
                     [0, 1, 1, 1, 0, 0],
                     [1, 1, 1, 0, 0, 0],
                     [1, 1, 1, 1, 1, 0]])
# create a view that the subarray as tuple and return unique indeies.
_, unique_index = np.unique(original.view(original.dtype.descr * original.shape[1]),
                            return_index=True)
# get unique set
print(original[unique_index])

还有另一个可能的解决方案

np.vstack({tuple(row) for row in a})