下面是做這件事的一種方法:
mask = (a > 0) & (a < N)
elements = a[mask]
indicies = np.arange(a.size)[mask]
b = [indicies[elements == i] for i in range(1, N)]
如果我們兩個時間:
import numpy as np
a = np.random.randint(0,100,1000)
N = 10
def original(a, N):
b = [[] for _ in range(N-1)]
for indx,elem in enumerate(a):
if 0<elem<N:
b[elem-1].append(indx)
return b
def new(a, N):
mask = (a > 0) & (a < N)
elements = a[mask]
indicies = np.arange(a.size)[mask]
return [indicies[elements == i] for i in range(1, N)]
「新」 的方式是相當(〜20倍)速度快:
In [5]: %timeit original(a, N)
100 loops, best of 3: 1.21 ms per loop
In [6]: %timeit new(a, N)
10000 loops, best of 3: 57 us per loop
結果相同:
In [7]: new_results = new(a, N)
In [8]: old_results = original(a, N)
In [9]: for x, y in zip(new_results, old_results):
....: assert np.allclose(x, y)
....:
In [10]:
「新」矢量化版本也對更長的序列進行縮放。如果我們對a
使用了一個百萬個項目的序列,原始解決方案需要稍微超過1秒,而新版本只需要17毫秒(加速~70倍)。
請說明你想要做什麼。你的代碼看起來應該是一種更直接的方式來實現你想要達到的目標。 – Carsten
可能你需要生成器或itertools。但我同意@Carsten。解釋你的目標是什麼。 Btw b可能是defaultdict(列表) –
只是爲了好玩,排序邏輯的單線是'b = [np.where(a == i)for i in range(1,N)]''。 – Carsten