2016-12-01 1 views
3

私は特定の次元で分割したいと思う配列があります。配列を分割する際に、前の要素の末尾部分を(各要素の先頭に)追加する必要があります。たとえば、前の分割からいくつかの要素を保持してnumpy配列を分割する方法は?

私の配列を[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]としましょう。私のsplit_size = 2pad_length = 1としましょう。 split_sizeは常に配列の長さの約数になります。結果の分割は、

[random, 0, 1], [1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]のようになります。私の分割には前の要素の最後の値が前に付加されていました。

言うまでもなく、私の配列は多次元であり、特定の次元に沿ってこれを行う効率的なベクター化された方法が必要です。

ここでは、randomの値を指定できます。

+0

ここ

は、それがどのように見えるだろうかです5、pad_length = 2 '?だから、私は最後の行が '[7 8 9 random random] 'であると推測しています。 – 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 decks、およびSO 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

おそらく、コピーよりもむしろデータのビューを生成する単なるスライシングであると考えても過言ではないでしょう。追加ディメンションに ':'を追加してください。 – acdr

1

stridesと別のアプローチであり、それは暗黙のうち、実際に割り当てるパッド入りのバージョンを持っているため、我々は割り当てられたメモリを超えた入力配列の先頭から後方ストライドと同じように、チートものとして見することができ最後にパッドされた領域に値を挿入します。 `split_size =: -

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]]) 
関連する問題