繁体   English   中英

在Numpy中获得向量集的并集的有效方法

[英]Efficient way to get union of set of vectors in Numpy

我正在尝试实现特定的二进制搜索算法。 “结果”一开始应为空集,在搜索过程中,“结果”变量将与我们获得的新结果合并。

基本上:

results = set()
for result in search():
  results = results.union(result)

但是这样的代码实际上np.union1d用于Numpy数组,因此我们使用np.union1d来实现此目的:

results = np.array([])
for result in search():
    result = np.union1d(results, result)

上面的代码也不起作用,因为例如,如果我们有两个向量a = [1,2,3]b=[3,4,5] ,则np.union1d(a, b)将返回:

[1, 2, 3, 4, 5]

但我希望它返回:

[[1, 2, 3], [3,4,5]]

由于没有重复的向量,因此,例如,如果我们有union([[1, 2, 3], [3,4,5]], [1,2,3]) ,则返回值应保持为:

[[1, 2, 3], [3,4,5]]


所以我想说我需要一个基于numpy数组的union

我还考虑过使用np.append(a, b)然后使用np.unique(x) ,但是这两个函数都将低维数组投影到高维数组。 np.append也具有axis=0属性,该属性保留插入的所有数组的尺寸,但是如果没有尺寸错误,我将无法高效地实现它。

题:

如何有效地实现基于向量的集合? 因此,并集中的点将被视为向量而不是标量,并将保留其向量形式和维数。

这是一些基本的设置操作。

定义一对列表(它们可以是np.array([1,2,3]) ,但这不是您所显示的。

In [261]: a = [1,2,3]; b=[3,4,5]

其中几个的列表:

In [263]: alist = [a, b, a]
In [264]: alist
Out[264]: [[1, 2, 3], [3, 4, 5], [1, 2, 3]]

我可以通过转换为元组并将它们放在一set来获得唯一值。

In [265]: set([tuple(i) for i in alist])
Out[265]: {(1, 2, 3), (3, 4, 5)}

我也可以将该列表转换为二维数组:

In [266]: arr = np.array(alist)
In [267]: arr
Out[267]: 
array([[1, 2, 3],
       [3, 4, 5],
       [1, 2, 3]])

并获得具有unique和axis参数的唯一行:

In [269]: np.unique(arr, axis=0)
Out[269]: 
array([[1, 2, 3],
       [3, 4, 5]])

比较时间

In [270]: timeit np.unique(arr, axis=0)
46.5 µs ± 142 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [271]: timeit set([tuple(i) for i in alist])
1.01 µs ± 1.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

将数组转换为列表或将列表转换为数组会增加一些时间,但基本模式仍然存在。

In [272]: timeit set([tuple(i) for i in arr.tolist()])
1.53 µs ± 13.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [273]: timeit np.unique(alist, axis=0)
53.3 µs ± 90.3 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

对于较大的,实际的源,相对时间可能会有所变化,但我希望元组的集合将保持最佳状态。 设置操作不是一个numpy unique会进行排序,然后消除重复项。 set使用散列方法,类似于Python用于字典的方法。

如果您必须从source迭代地收集值,建议您建立一个列表,并进行一次set/unique

alist = []
for x in source():
    alist.append(x)

或以下之一:

alist = [x for x in source()]
alist = list(source())
alist = [tuple(x) for x in source()]
alist = [tuple(x.tolist()) for x in source()]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM