如果你使用線性索引數組,你似乎可以顯着提升性能。這裏有一個量化的實現來解決我們的情況下,類似@rth's answer,但使用線性索引 -
# Get floor-ed indices
idx = np.floor(input).astype(np.int)
# Calculate linear indices
lin_idx = idx[:,0]*lat_len + idx[:,1]
# Index raveled/flattened version of binary_matrix with lin_idx
# to extract and form the desired output
out = input[binary_matrix.ravel()[lin_idx] ==1]
因此,總之我們:
out = input[binary_matrix.ravel()[idx[:,0]*lat_len + idx[:,1]] ==1]
運行測試 -
這部分比較在此解決方案中針對使用行列索引的other solution提出了一種方法。
情況#1(原始datasizes):
In [62]: lat_len = 100 # lattice length
...: input = np.random.random(size=(1000,2)) * lat_len
...: binary_matrix = np.random.choice(2, lat_len * lat_len).
reshape(lat_len, -1)
...:
In [63]: idx = np.floor(input).astype(np.int)
In [64]: %timeit input[binary_matrix[idx[:,0], idx[:,1]] == 1]
10000 loops, best of 3: 121 µs per loop
In [65]: %timeit input[binary_matrix.ravel()[idx[:,0]*lat_len + idx[:,1]] ==1]
10000 loops, best of 3: 103 µs per loop
情況#2(放大datasizes):
In [75]: lat_len = 1000 # lattice length
...: input = np.random.random(size=(100000,2)) * lat_len
...: binary_matrix = np.random.choice(2, lat_len * lat_len).
reshape(lat_len, -1)
...:
In [76]: idx = np.floor(input).astype(np.int)
In [77]: %timeit input[binary_matrix[idx[:,0], idx[:,1]] == 1]
100 loops, best of 3: 18.5 ms per loop
In [78]: %timeit input[binary_matrix.ravel()[idx[:,0]*lat_len + idx[:,1]] ==1]
100 loops, best of 3: 13.1 ms per loop
因此,利用此線性索引的性能提升似乎是約20%
- 30%
。
令人難以置信。你能解釋一下什麼樣的改變在性能上有很大的不同,例如int的用法? –
性能上的差異是因爲我們避免了python中的for循環,並且使用高級numpy索引來代替(我在上面添加了一個鏈接),它在C中更加高效地編碼。轉換爲整數只是一個副作用,因爲索引不能有浮點數'dtype',並且必須是整數或布爾值。 – rth