2016-09-13 38 views
2

我需要實現的是獲取所有索引的數組,其中在我的數據數組中填充零和數字是從零到一步。我需要非常快速的解決方案,因爲我必須與數以百萬計的hundrets milions數組一起工作。它將在計算中心運行。例如..查找numpy數組中所有指定匹配的兩個數的所有匹配

data_array = np.array([1,1,0,1,1,1,0,0,0,1,1,1,0,1,1,0]) 
result = [3,9,13] 
+0

所以,也無論是發佈的解決方案,爲您的工作? – Divakar

回答

3

試試這個:

In [23]: np.where(np.diff(a)==1)[0] + 1 
Out[23]: array([ 3, 9, 13], dtype=int64) 

時序100M元素的數組:

In [46]: a = np.random.choice([0,1], 10**8) 

In [47]: %timeit np.nonzero((a[1:] - a[:-1]) == 1)[0] + 1 
1 loop, best of 3: 1.46 s per loop 

In [48]: %timeit np.where(np.diff(a)==1)[0] + 1 
1 loop, best of 3: 1.64 s per loop 
+0

哦,我知道numpy有一個diff函數 - 雖然認爲它是一個數組方法。我喜歡這個簡潔。 +1 –

+0

@PaulH,謝謝!我也喜歡(已經;)你的答案 - 因爲我不知道'np.nonzero()'函數,所以我今天從你的答案中學到了新東西 – MaxU

1

這裏的程序:數組的

  1. 計算的差異
  2. 查找索引,其中DIFF == 1
  3. 加1的結果(B/C len(diff) = len(orig) - 1

那麼試試這個:

index = numpy.nonzero((data_array[1:] - data_array[:-1]) == 1)[0] + 1 
index 
# [3, 9, 13] 
+0

我認爲你的解決方案應該更快,因爲「非零」函數... – MaxU

+0

FWIW,我在我的機器上看到'nonzero'和'where'之間沒有任何區別(對於10 ** 6個隨機位,兩者都是6.6 ms左右) –

+0

您的解決方案大約是。在10 ** 8陣列上速度提高12%......我將發佈時間... – MaxU

0

好非常感謝你們所有的人。非零的解決方案可能對我更好,因爲我需要知道0-> 1以及1-> 0的步驟,最後計算差異。所以這是我的解決方案。任何其他的建議表示讚賞。)

i_in = np.nonzero( (data_array[1:] - data_array[:-1]) == 1 )[0] +1 
i_out = np.nonzero( (data_array[1:] - data_array[:-1]) == -1 )[0] +1 

i_return_in_time = (i_in - i_out[:i_in.size]) 
0

因爲它是充滿0s1s一個數組,你可以只是比較,而不是一個移版本之間進行算術運算,直接給我們的布爾數組中獲益,這可能請送至np.flatnonzero以獲取指數和最終產出。

因此,我們必須像這樣的實現 -

np.flatnonzero(data_array[1:] > data_array[:-1])+1 

運行測試 -

In [26]: a = np.random.choice([0,1], 10**8) 

In [27]: %timeit np.nonzero((a[1:] - a[:-1]) == 1)[0] + 1 
1 loop, best of 3: 1.91 s per loop 

In [28]: %timeit np.where(np.diff(a)==1)[0] + 1 
1 loop, best of 3: 1.91 s per loop 

In [29]: %timeit np.flatnonzero(a[1:] > a[:-1])+1 
1 loop, best of 3: 954 ms per loop 
相關問題