2013-03-20 20 views
2

鑑於陣列如何有效地從數組中選擇多個切片?

d = np.random.randn(100) 

和索引陣列

i = np.random.random_integers(low=3, high=d.size - 5, size=20) 

我怎樣纔能有效地創建一個二維數組r

r.shape = (20, 8) 

使得對於所有j=0..19

r[j] = d[i[j]-3:i[j]+5] 

在我的情況下,數組非常大(〜200000而不是100和20),所以快速的東西會很有用。

+0

「低」和「高」有什麼區別嗎?像'low = 0,high = d.size - 8'和'd [i [j]:i [j] +8]'? – Kabie 2013-03-20 16:04:49

+0

是的,它確實有所作爲。如果'i'的元素是'<3',那麼'i [j] -3'是負數。類似的上限。 – 2013-03-20 16:13:49

+0

但是如果'all(0 <= elem <= 92 for elem in i)is True'那麼'd [i [j]:i [j] +8]'是一樣的,對嗎? – Kabie 2013-03-20 16:21:16

回答

1

您可以創建數據的窗景,即一個(93, 8)陣列,其中項目[i, j]是你原來的數組的項目[i+j],如:

>>> from numpy.lib.stride_tricks import as_strided 
>>> wd = as_strided(d, shape=(len(d)-8+1, 8), strides=d.strides*2) 

現在,您可以提取您所需的切片爲:

>>> r = wd[i-3] 

請注意,wd只是您的原始數據視圖,因此它不需要額外的內存。在您提取r任意索引的那一刻,就會複製數據。因此,根據您希望使用r陣列的方式,您可能希望儘可能延遲或者甚至完全避免:您可以始終訪問行r[j]作爲wd[j-3]而不觸發副本。

+1

除非您首先重寫函數,否則請勿使用此處。很高興知道這個比賽的速度更快,但這至少是一個非常糟糕的主意(當然不會更快)。 – seberg 2013-03-20 16:19:36

+0

@seberg我猜這是複製,無論發生什麼都必須發生,這使得它不好主意,對吧?將編輯我的答案:謝謝! – Jaime 2013-03-20 16:28:03

+0

那麼,正常的切片將不會做臨時副本,我相信...所以如果你只有幾個項目,你可能會膨脹記憶大時間... – seberg 2013-03-20 16:37:59

相關問題