2015-02-10 51 views
1

我有類似np.arange([100000])的東西,我需要多次檢索兩個索引之間的數據。目前我運行這個很慢numpy array快速切片多次

data = np.arange([100000]) 
# This array usually contains thousands of slices 
slices = np.array([ 
     [1, 4], 
     [10,20], 
     [100,110], 
     [1000,1220] 
]) 

# One way i have been doing it 
np.take(data, [i for iin, iout in slices for idx in range(iin, iout)]) 
# The other way 
[data[iin:iout] for iin, iout in slices] 

兩種方式都很慢。我需要這個速度非常快。我在尋找這樣的東西。

data[slices[:,0], slices[:,1]] 

回答

1

slices和一些時序data = np.arange(2000)

take,糾正:

In [360]: timeit np.take(data, [idx for iin, iout in slices for idx in range(iin,iout)]) 
10000 loops, best of 3: 92.5 us per loop 

In [359]: timeit data[[idx for iin, iout in slices for idx in range(iin,iout)]] 
10000 loops, best of 3: 92.2 us per loop 

你的第二版(修正) - 相當好一點

In [361]: timeit np.concatenate([data[iin:iout] for iin,iout in slices]) 
100000 loops, best of 3: 15.8 us per loop 

使用np.r_連接切片 - 不是比你的第一次有很大的改進。

In [362]: timeit data[np.r_[tuple([slice(i[0],i[1]) for i in slices])]] 
10000 loops, best of 3: 79 us per loop 
In [363]: timeit np.r_[tuple([slice(i[0],i[1]) for i in slices])] 
10000 loops, best of 3: 67.5 us per loop 

構建索引佔用大部分時間。

當然,這個規模的排名可能會隨着問題的擴大而改變。

由於您的切片長度不同,因此沒有太多希望以矢量化方式生成它們,即「並行」。我不知道cython的實現是否會加快它的速度。

來自較早類似問題的更多計時 https://stackoverflow.com/a/11062055/901925