2017-03-07 67 views
1

我有一個非常大的numpy的陣列,我想,如果它是唯一的對它進行排序和測試。有效地確定是否大排序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行和列相同的(巨大)號碼。

在此先感謝。

+0

是我們這只是玩具示例數據,或者是你真正用2^27個或更多的32位整數的工作? –

+0

@StefanPochmann我確實有這個數的整數工作,因爲這是一個科學的應用。 – Marco

+0

然後,您幾乎可以用'False' :-)替換您的唯一性檢查。非常快,在10^500000次嘗試中只有一次錯誤,即幾乎從不錯過。 –

回答

4

您可以檢查是否有兩個或兩個以上相同的值彼此相鄰(在排序後的數組非唯一值),而它們的區別比較0

numpy.any(numpy.diff(slices) == 0) 

要知道,雖然numpy的將創建兩個中間數組:一個具有差異值,一個具有布爾值。

+0

謝謝!我不知道函數''''numpy.diff'''。我把它甚至更好(I猜)通過使用'''numpy.diff(切片)。所有()''',只創建一箇中間陣列。 – Marco

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 
+1

不錯,我也在考慮切片,但是很快就駁回了這個想法:-) –

相關問題