有效地确定大型有序numpy数组是否只有唯一值

时间:2017-03-07 15:22:27

标签: python arrays sorting numpy unique

我有一个非常大的numpy数组,我想对它进行排序并测试它是否是唯一的。

我知道函数numpy.unique但它会再次对数组进行排序以实现它。

我需要排序先验的数组的原因是因为来自argsort函数的返回键将用于重新排序另一个数组。

我正在寻找一种方法(argsort和唯一测试),而无需再次对数组进行排序。

示例代码:

import numpy as np
import numpy.random

# generating random arrays with 2 ^ 27 columns (it can grow even bigger!)
slices = np.random.random_integers(2 ** 32, size = 2 ** 27)
values = np.random.random_integers(2 ** 32, size = 2 ** 27)

# get an array of keys to sort slices AND values
# this operation takes a long time
sorted_slices = slices.argsort()

# sort both arrays
# it would be nice to make this operation in place
slices = slices[sorted_slices]
values = values[sorted_slices]

# test 'uniqueness'
# here, the np.unique function sorts the array again
if slices.shape[0] == np.unique(slices).shape[0]:
    print('it is unique!')
else:
    print('not unique!')

数组slicesvalues都有1行和相同(巨大)列数。

提前致谢。

2 个答案:

答案 0 :(得分:4)

您可以通过将它们的差异与0

进行比较来检查彼此相邻的两个或更多相等值(排序数组中的非唯一值)
numpy.any(numpy.diff(slices) == 0)

请注意,numpy会创建两个中间数组:一个具有差值,一个具有布尔值。

答案 1 :(得分:3)

这是一种利用slicing而不是实际区分的方法,我们可以将每个元素与前一个元素进行比较而不实际计算区分值,如此 -

~((slices[1:] == slices[:-1]).any())

运行时测试 -

In [54]: slices = np.sort(np.random.randint(0,100000000,(10000000)))

# @Nils Werner's soln
In [55]: %timeit ~np.any(np.diff(slices) == 0)
100 loops, best of 3: 18.5 ms per loop

# @Marco's suggestion in comments
In [56]: %timeit np.diff(slices).all()
10 loops, best of 3: 20.6 ms per loop

# Proposed soln in this post
In [57]: %timeit ~((slices[1:] == slices[:-1]).any())
100 loops, best of 3: 6.12 ms per loop