python 2-D数组获取np.unique或union1d的函数

时间:2016-08-22 15:35:35

标签: python-2.7 numpy

如下我有一个二维列表/数组

list1 = [[1,2],[3,4]]
list2 = [[3,4],[5,6]]

如何使用union1d(x,y)函数将list1和list2作为一个列表

list3 = [[1,2],[3,4],[5,6]]

2 个答案:

答案 0 :(得分:1)

union1d就是:

unique(np.concatenate((ar1, ar2)))

因此,如果您有查找唯一行的方法,那么您就有了解决方案。

如建议的链接和其他地方所述,您可以通过将数组转换为1d结构化数组来完成此操作。这里的简单版本是

如果arr是:

arr=np.array([[1,2],[3,4],[3,4],[5,6]])

结构化等价物(视图,相同数据):

In [4]: arr.view('i,i')
Out[4]: 
array([[(1, 2)],
       [(3, 4)],
       [(3, 4)],
       [(5, 6)]], 
      dtype=[('f0', '<i4'), ('f1', '<i4')])

In [5]: np.unique(arr.view('i,i'))
Out[5]: 
array([(1, 2), (3, 4), (5, 6)], 
      dtype=[('f0', '<i4'), ('f1', '<i4')])

并回到2d int:

In [7]: np.unique(arr.view('i,i')).view('2int')
Out[7]: 
array([[1, 2],
       [3, 4],
       [5, 6]])

此解决方案确实需要熟悉化合物dtypes。

使用return_index保存返回视图。我们可以使用该索引直接索引arr

In [54]: idx=np.unique(arr.view('i,i'),return_index=True)[1]

In [55]: arr[idx,:]
Out[55]: 
array([[1, 2],
       [3, 4],
       [5, 6]])

对于它的价值,unique执行sort,然后使用掩码方法删除相邻的重复项。

sort需要1d数组,其余工作在2d

此处arr已经排序

In [42]: flag=np.concatenate([[True],(arr[1:,:]!=arr[:-1,:]).all(axis=1)])

In [43]: flag
Out[43]: array([ True,  True, False,  True], dtype=bool)

In [44]: arr[flag,:]
Out[44]: 
array([[1, 2],
       [3, 4],
       [5, 6]])

https://stackoverflow.com/a/16971324/901925显示这与lexsort一起使用。

=====

提到np.union1d让我和Divakar专注于numpy方法。但它从列表(列表)开始,使用Python集方法可能会更快。

例如,使用list和set comprehensions:

In [99]: [list(x) for x in {tuple(x) for x in list1+list2}]
Out[99]: [[1, 2], [3, 4], [5, 6]]

您也可以为每个列表设置集合,然后设置union

需要进行tuple转换,因为列表不可用。

答案 1 :(得分:0)

一种方法是将这两个输入数组与np.vstack垂直堆叠,然后在其中查找唯一的行。这将是内存密集型的,因为我们之后会从中丢弃行。

另一种方法是在第一个数组中找到它所独有的行,即不存在于第二个数组中,因此只是将这些独占行与第二个数组一起堆叠。当然,这会假设每个输入数组中都有唯一的行。

这种建议的节省内存的实现的关键是从第一个数组中获取那些独占行。对于同样的情况,我们将每行转换为线性索引等效,将每行视为n维网格上的索引元组,n是输入数组中的列数。因此,假设输入数组为arr1arr2,我们就会有这样的实现 -

# Get dim of ndim-grid on which linear index equivalents are to be mapped
dims = np.maximum(arr1.max(0),arr2.max(0)) + 1

# Get linear index equivalents for arr1, arr2
idx1 = np.ravel_multi_index(arr1.T,dims)
idx2 = np.ravel_multi_index(arr2.T,dims)

# Finally get the exclusive rows and stack with arr2 for desired o/p
out = np.vstack((arr1[~np.in1d(idx1,idx2)],arr2))

示例运行 -

In [93]: arr1
Out[93]: 
array([[1, 2],
       [3, 4],
       [5, 3]])

In [94]: arr2
Out[94]: 
array([[3, 4],
       [5, 6]])

In [95]: out
Out[95]: 
array([[1, 2],
       [5, 3],
       [3, 4],
       [5, 6]])

有关设置这些线性索引等效项的更多信息,请参阅this post