2016-04-22 18 views
2

私は配列A1_ijkを持っていて、それをA2_ijmnkにブロードキャストしたいのですが、m=nの場合のみです。それ以外の場合はA2に0を書きます。もちろん私は、新しい空の配列を作成し、このようなA1でそれを埋めることができます。私は、これは、より効率的な方法で行うことができることが感じストライドでnumpy配列を構成する

import numpy as np 
A1 = np.random.rand(100, 5, 3) 
A2 = np.zeros((100, 5, 2, 2, 3)) 
A2[..., 0, 0, :] = A1 
A2[..., 1, 1, :] = A1 

。私はas_stridedを試してみました:

as_strided = np.lib.stride_tricks.as_strided 
sz = A1.itemsize 
A2 = as_strided(A1, shape=(100,5,2,2,3), strides=(5*3*sz, 3*sz, 0, 0, sz)) 

ともbroadcast_to

broadcast_to = np.lib.stride_tricks.broadcast_to 
A2=broadcast_to(A1[...,None,None,:], (100,5,2,2,3)) 

残念ながら、両方の方法がA1値を持つすべてのm, nペアを埋めます。

私はストライドを使用して実際のデータをコピーせずに必要なシェイプの配列を作成することができますか?

+0

は 'A2.shape [2]、A2.shape [3う] 'be'(2,2) '実際のケースでも?もしそうであれば、そのような小さい次元では、コードは読みやすさとパフォーマンスの面では大丈夫です。 – Divakar

+0

これは、 '(2,2)、'(3,3) 'とすることができますが、'(m、n、o、 'または'(3,3,3,3) 'となります。しかし、私はかなりの頻度で「A2」を構成しなければなりません。私はストライドで、私はA1だけを更新し、すぐにA2の変化を見ることができると期待した。 – mrkwjc

+0

「A1」を連続して構築し、「A2」に「A1」の表示をさせようとするのではなく、「A1」を「A2」の表示にすることはできますか? – user2357112

答えて

2

私はストライドを使用して実際のデータをコピーせずに必要なシェイプの配列を作成するためにストライドを使用することができますか?

そうではありません。これを見るための簡単な方法として、配列にゼロがない場合、その配列を表示することができないため、必要な非対角ゼロを得ることができます。

+0

まあ、ストライドすることができますか? – mrkwjc

+0

@mrkwjc:あなたは何とか複数の別々のバッファーへのビューで構成される配列を持つ必要があります。 NumPyはそれをしません。 – user2357112

0

Youdは少なくともn個のゼロをデータで埋め込む必要があります。ストライド[n] == - ストライド[m]を設定して、目的の効果を達成し、順序n * mのゼロを割り当てるのを避けることができます。

しかし、より大きな画像を見れば、より洗練された解決策が必要であることが分かります。

+0

私はこれのようなものはここで考えられていると思う:http://stackoverflow.com/questions/18026541/make-special-diagonal-matrix-in-numpy – mrkwjc

+0

はい、2番目の答えは私が話していることの線に沿っている;余分な軸を除いて、あなたのケースはあまり変わってはいけません –

1

np.diag_indicesで簡単にコーディングすることができます。私は、ストライドされたソリューション(可能であれば)に比べて効率についてはありません。私は

まずインデックス

In [2]: np.diag_indices(2) 
Out[2]: (array([0, 1]), array([0, 1])) 

よりシンプルなスタートに十分な私の開発の歴史を簡略化することができるかどうかを見てみましょう。最初は2次元を必要とせず、形状を変更することができます。私たちは、おそらく終わるの寸法を必要としませんが、私は今のためにそれを残しておきます:

In [4]: A2=np.zeros((4,2,2,3),int)  
In [5]: A2[:,0,0,:]=A1 
In [6]: A2[:,1,1,:]=A1 

In [7]: A2 
Out[7]: 
array([[[[ 0, 1, 2], 
     [ 0, 0, 0]], 

     [[ 0, 0, 0],  
     [[[ 3, 4, 5], 
     [ 0, 0, 0]], 

     [[ 0, 0, 0], 
     [ 3, 4, 5]]], 


     ... 

     [[[ 9, 10, 11], 
     [ 0, 0, 0]], 

     [ 0, 1, 2]]], 

      ... 
     [[ 0, 0, 0], 
     [ 9, 10, 11]]]]) 

オルタナティブ:

In [8]: A3=np.zeros((4,2,2,3),int) 

In [9]: i,j=np.diag_indices(2) 

In [10]: A3[:,i,j,:]=A1 
... 
ValueError: shape mismatch: value array of shape (4,3) could not be broadcast to indexing result of shape (2,4,3) 

形状の不一致

In [3]: A1=np.arange(12).reshape(4,3) 

今リファレンス・ソリューションを構築します最初の試み

In [12]: A2[:,i,j,:] 
Out[12]: 
array([[[ 0, 1, 2], 
     [ 0, 1, 2]], 

     [[ 3, 4, 5], 
     [ 3, 4, 5]], 

     [[ 6, 7, 8], 
     [ 6, 7, 8]], 

     [[ 9, 10, 11], 
     [ 9, 10, 11]]]) 

In [13]: A2[:,i,j,:].shape 
Out[13]: (4, 2, 3) 

A1を変更して宛先スロットにブロードキャストできるようにする必要があります。

In [14]: A1.shape 
Out[14]: (4, 3) 

In [15]: A3[:,i,j,:] = A1[:,None,:] 

In [16]: np.allclose(A2,A3) 
Out[16]: True 

A2[...,i,j,:] = A1[...,None,:]はあなたの例を処理する必要があります。

アンも簡単なバージョンは、3dに消費する、1Dアレイで始まり

In [21]: a1=np.arange(3) 

In [22]: a3=np.zeros((2,2,3),int) 

In [23]: a3[...,i,j,:]=a1[...,None,:] 

In [24]: a3[i,j,:]=a1 # equivalent since a1[None,:] is automatic 

In [25]: a3 
Out[25]: 
array([[[0, 1, 2], 
     [0, 0, 0]], 

     [[0, 0, 0], 
     [0, 1, 2]]]) 

a3a1値の繰り返しパターンを有していません。それとも?

In [36]: a3.flatten() 
Out[36]: array([0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2]) 

あなたが発見したとして、それはas_stridesですべてのスロットを埋めるのは簡単だが、ハードだけで対角線を埋めるために:

In [46]: ast(a1,shape=a3.shape, strides=(0,0,4)) 
Out[46]: 
array([[[0, 1, 2], 
     [0, 1, 2]], 

     [[0, 1, 2], 
     [0, 1, 2]]]) 
関連する問題