2016-12-01 114 views
3

我有一個numpy數組,我希望在某個維度上分割。在分割數組時,我需要在每個元素的開頭添加前一個元素的尾部。例如,如何分割numpy數組保留前一個分割的幾個元素?

讓我的數組爲[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]。讓我的split_size = 2pad_length = 1split_size將始終是數組長度的除數。我的合成分割看起來像,

[random, 0, 1], [1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]。我的分割全部由前一個元素的最後一個值作爲前綴。不用說,我的數組是多維的,我需要一個高效的矢量化方式來沿着一定的維度做到這一點。

在這裏,我可以提供random的值。

+0

不會,我們需要填充的尾隨方太,像給定輸入:'split_size = 5,pad_length = 2'?所以,我猜測最後一行是:[隨機隨機] [7 8 9]。 – Divakar

+0

爲什麼?對於這些參數,我應該得到這個 - > [[隨機,隨機,0,1,2,3,4],[3,4,5,6,7,8,9]'。如果問題不明確,我會很樂意在您指導下改進它! – martianwars

+0

啊我得到了錯誤的參數。我的意思是如果'split_size = 3,pad_length = 2'? – Divakar

回答

2

聽起來像是as_strided的工作。

as_strided在陣列上返回一個高效的內存視圖並可用於檢索數組上的移動窗口。關於它的numpy文檔很少,但有一些體面的博客文章,online slide decksSO issues,你可以找到更詳細的解釋它。

>>> import numpy as np 
>>> from numpy.lib.stride_tricks import as_strided 
>>> a = np.arange(10) 
>>> split_size = 2 
>>> pad_length = 1 
>>> random = -9 
>>> # prepend the desired constant value 
>>> b = np.pad(a, (pad_length, 0), mode='constant', constant_values=random) 
>>> # return a memory efficient view on the array 
>>> as_strided(b, 
...  shape=(b.size//split_size, split_size + pad_length), 
...  strides=(b.strides[0]*split_size, b.strides[0])) 
... 
array([[-9, 0, 1], 
     [ 1, 2, 3], 
     [ 3, 4, 5], 
     [ 5, 6, 7], 
     [ 7, 8, 9]]) 

注意,如果新的步伐去出界,你會看到鄰近的內存出現在數組的末尾存儲器內容。

+0

我認爲你的意思是'split_size + pad_length'。很好的答案! :D – martianwars

+0

的確,我做到了。更新,謝謝! –

+0

工程就像一個魅力。非常感謝! – martianwars

0

下接近:

arr = np.array([0,1,2,3,4,5,6,7,8,9]) 
[arr[max(0, idx-1):idx+2] for idx in range(0, len(arr), 2)] 

唯一的區別是第一個不具有領先random,正如你所說的那樣。

+0

這對於更大的數組是否有效? – martianwars

+1

可能它不會太壞,因爲它只是切片,它會產生數據的視圖,而不是副本。只要確保爲其他維度添加':'s即可。 – acdr

1

這裏列出的是與strides另一種方法,並可以被看作是一個作弊的東西,因爲我們落後,超出分配的內存輸入數組的開始邁出了它有一個軟墊版本含蓄和實際分配值轉換爲結尾處的待填充區域。

下面是它會是什麼樣子 -

def padded_sliding_windows(a, split_size, pad_length, padnum): 
    n = a.strides[0] 
    L = split_size + pad_length 
    S = L - pad_length 
    nrows = ((a.size + pad_length -L)//split_size)+1 
    strided = np.lib.stride_tricks.as_strided 
    out = strided(a[split_size - 1:], shape=(nrows,L), strides=(S*n,-n))[:,::-1] 
    out[0,:pad_length] = padnum 
    return out 

很少的樣品試驗 -

In [271]: a = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) 

In [272]: padded_sliding_windows(a, split_size = 2, pad_length = 1, padnum = 100) 
Out[272]: 
array([[100, 0, 1], 
     [ 1, 2, 3], 
     [ 3, 4, 5], 
     [ 5, 6, 7], 
     [ 7, 8, 9], 
     [ 9, 10, 11]]) 

In [273]: padded_sliding_windows(a, split_size = 3, pad_length = 2, padnum = 100) 
Out[273]: 
array([[100, 100, 0, 1, 2], 
     [ 1, 2, 3, 4, 5], 
     [ 4, 5, 6, 7, 8], 
     [ 7, 8, 9, 10, 11]]) 

In [274]: padded_sliding_windows(a, split_size = 4, pad_length = 2, padnum = 100) 
Out[274]: 
array([[100, 100, 0, 1, 2, 3], 
     [ 2, 3, 4, 5, 6, 7], 
     [ 6, 7, 8, 9, 10, 11]])