2017-08-15 9 views
11

numpy.lib.stride_tricks.as_stridedの結果は、NumPy配列のdtypeに依存しますか?numpy.as_stridedの結果は入力dtypeに依存しますか?

この質問はアレイを横断する際、各次元におけるステップバイトの

タプル.stridesの定義から生じます。

ここで他の質問で使用した以下の機能を使用してください。 1dまたは2dの配列をとり、長さがwindowの重複ウィンドウを作成します。結果は入力より1次元大きくなります。そのため、ストライドの定義とDTYPE float32float64のために、例えば、そうでない場合と同等の配列の

def rwindows(a, window): 
    if a.ndim == 1: 
     a = a.reshape(-1, 1) 
    shape = a.shape[0] - window + 1, window, a.shape[-1] 
    strides = (a.strides[0],) + a.strides 
    windows = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides) 
    return np.squeeze(windows) 

# examples 
# rwindows(np.arange(5), window=2) 
# rwindows(np.arange(20).reshape((5,4)), window=2) 

は異なる進歩、これは今まで以上に私rwindows機能を爆破されますがありますか?

私はテストしようとしましたが、それは非徹底的な方法であり、(1)関数docからの免責事項/警告が私がここで尋ねていることと何か関係がある(2)異なるdtypeを持つ等価ではない配列がなぜ上記のように異なる結果をもたらすのかを説明する。

+3

私は2つの問題を見てきました。シェイプが正しくない場合は、バッファの最後から「ストライド」することができます。すべてのインデックス値が有効であることを保証するための保護手段はありません。次に、ストライドされた配列の多くの操作がコピーを作成します。そのコピーは、元の配列またはストライドビューよりもはるかに大きくなる可能性があります。多次元ストライド(2または3dウィンドウ)では特にそうです。 – hpaulj

+0

ハァッ。その関数が実際にそれを現在文書化しているほど普及しているように見えます。 – user2357112

答えて

4

いいえ、as_stridedの警告は、実際にはデータのサイズに関係しない2つの問題のためのものであり、結果のビューへの書き込みの結果が増えます。

  1. まず、aにメモリにview = as_strided(a . . .)のみポイントを確保するためには保護がありません。このため、as_stridedに電話する前に、あまりにも多くの意図的な準備作業が行われています。あなたのアルゴリズムがオフの場合は、容易にviewがメモリを指していて、aにはなく、実際にはガベージ、他の変数、またはオペレーティングシステムに対処されている可能性があります。そのビューに書き込むと、データが失われたり、配置が間違ったり、壊れたりする可能性があります。 。 。コンピュータをクラッシュさせることがあります。

具体的な例として、使用している入力にどのくらいの差があるかによって異なります。 stridesa.stridesに設定しているので、動的です。 assertの場合、dtypeaは、objectのような変わったものではありません。あなたは常にwindowよりも大きくなっている2-D aを持っていることを確信している場合

は、おそらくあなたのアルゴリズムで罰金になりますが、あなたはまた、assertを確認することができます。そうでない場合は、as_strided出力がn-d aアレイで動作することを確認してください。例えば:

shape = a.shape[0] - window + 1, window, a.shape[-1] 

はおそらくN-D入力を受け入れるために

shape = (a.shape[0] - window + 1, window) + a.shape[1:] 

である必要があります。おそらくは、悪いメモリを参照する限り問題にはなりませんが、shapeはより多くの次元がある場合はaの間違ったデータを参照します。

  1. 第2に、作成されたビューは同じデータブロックを複数回参照します。そのビュー(view = fooまたはbar(. . ., out = view))への並列書き込みを実行すると、結果はunpredictableとなる可能性があります。あなたが問題を恐れているとas_stridedビュー(あなたはそれが一般的に使用されるほとんどの畳み込みアプリケーションにないよう)に記述する必要がない場合は、あなたは常にwritable = Falseとしてそれを設定することができ、言っ

stridesおよび/またはshapeが間違っていても、両方の問題を防ぐことができます。

EDIT:あなたはコピー(のような.flatten()や空想のインデックス、それの大きな塊)を作るviewに何かをすればとしては、これら二つの問題に加えて、@hpauljが指摘し、それが引き起こす可能性がありますMemoryError

関連する問題