Python 2.7 python 2-D数组将函数获取为np.unique或union1d

Python 2.7 python 2-D数组将函数获取为np.unique或union1d,python-2.7,numpy,Python 2.7,Numpy,如下所示,我有一个二维列表/数组 list1 = [[1,2],[3,4]] list2 = [[3,4],[5,6]] 如何使用函数asunion1d(x,y)将列表1和列表2作为一个列表 list3 = [[1,2],[3,4],[5,6]] union1d只做: unique(np.concatenate((ar1, ar2))) 因此,如果您有一种查找唯一行的方法,那么您就有了解决方案 如建议的链接和其他地方所述,可以通过将阵列转换为一维结构化阵列来实现这一点。这里是简单的版本 如

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

list1 = [[1,2],[3,4]]
list2 = [[3,4],[5,6]]
如何使用函数as
union1d(x,y)
将列表1和列表2作为一个列表

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

union1d
只做:

unique(np.concatenate((ar1, ar2)))
因此,如果您有一种查找唯一行的方法,那么您就有了解决方案

如建议的链接和其他地方所述,可以通过将阵列转换为一维结构化阵列来实现这一点。这里是简单的版本

如果
arr
为:

arr=np.array([[1,2],[3,4],[3,4],[5,6]])
结构化等价物(视图、相同数据):

此解决方案确实需要对复合数据类型有一定的熟悉

使用
return\u 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
进行
排序
,然后使用掩码方法删除相邻的重复项

排序需要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]])
显示了如何使用
lexsort

================

提到
np.union1d
让我和Divakar开始关注numpy方法。但是从列表开始,使用Python集合方法可能会更快

例如,使用列表和集合理解:

In [99]: [list(x) for x in {tuple(x) for x in list1+list2}]
Out[99]: [[1, 2], [3, 4], [5, 6]]
您还可以为每个列表获取集合,并执行集合
联合


由于列表不可散列,因此需要进行
元组转换。

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

另一种方法是在第一个数组中查找对其独占的行,即在第二个数组中不存在的行,从而将这些独占行与第二个数组一起堆叠。当然,这将假定每个输入数组中都有唯一的行

这种建议的内存节省实现的关键是从第一个数组中获取那些排他的行。同样,我们将每一行转换为一个线性索引等价物,将每一行视为n维网格上的索引元组,
n
是输入数组中的列数。因此,假设输入数组为
arr1
arr2
,我们将有这样一个实现-

# 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]])

有关设置这些线性索引等价物的更多信息,请参阅。

此处的答案既涉及简单情况(“唯一”子列表表示“位精确”),也涉及浮点情况(如果两个子列表在某个公差范围内,您希望将它们视为“相等”)。这回答了你的问题吗?@Ahmed Fasih ths,为了得到唯一的二维列表,答案解决了我唯一的问题,这个问题我主要想找到一个函数,可以合并两个列表。对于小列表,你另一个SO问题中的Python列表方法比这些
numpy
方法更快。将列表转换为数组需要时间。基于另一个SO问题的列表版本:
[list(x)for x in{tuple(x)for x in list1+list2}]
所有示例都使用
unique
,而不是
union1d
。这是故意的吗?只是在串联后更容易处理一个数组
union1d
以串联开始。Divakar试图证明在不进行串联的情况下执行并集。
in1d
分别对两个输入执行
unique
,然后对它们的串联执行
unique
类似操作。@hpaulj很高兴知道!但不应执行返回索引的操作。
# 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]])