2017-03-23 5 views
0

私は、異なる長さの配列を含むサイズ125,30,360の2つの行列(m1とm2)を持っています。私がしたいのは、これらの配列を要素ごとに連結することです。今のところ、私は、forループでこれを行う:配列を含むNumpy行列を2つ組み合わせる

for i in range(125): 
    for j in range(30): 
     for k in range(360): 
      m1[i, j, k] = np.hstack(m1[i, j, k], m2[i, j, k]) 

だから結果m1はまだ前と同じ大きさを持っている、しかし、各要素内の配列は、長さを変更しました。上記の例はうまくいきますが、時間がかかります(コードで何度もやっています)。それを行うより速い方法がありますか?

m1 = np.zeros([125, 30, 360], dtype=np.ndarray) 
for i in range(125): 
    for j in range(30): 
     for k in range(360): 
      m1[i,j,k] = np.array([]) 

EDIT:m1m2はそれが物事を明確にした場合、次のように作成された私のテキストは、上記のいくつかの混乱につながるている、少し不明でした。私はそれで、私がしたいことの下に小さな例を作りました。

ステップ1:m1とm2を作成します。

m1 = np.zeros([2, 2], dtype=np.ndarray) 
m2 = np.zeros([2, 2], dtype=np.ndarray) 
for i in range(2): 
    for j in range(2): 
     m1[i, j] = np.array(range(i+j)) 
     m2[i, j] = np.array(range(i+j+1)) 

ステップ1の結果:

m1 = array([[array([], dtype=float64), array([0])], 
    [array([0]), array([0, 1])]], dtype=object) 
m2 = array([[array([0]), array([0, 1])], 
    [array([0, 1]), array([0, 1, 2])]], dtype=object) 

ステップ2:連結し、M1とM2。中

for i in range(2): 
    for j in range(2): 
     m1[i, j] = np.hstack((m1[i, j], m2[i, j])) 

ステップ2の結果:

m1 = array([[array([ 0.]), array([0, 0, 1])], 
    [array([0, 0, 1]), array([0, 1, 0, 1, 2])]], dtype=object) 

だから、質問は:2がより速く行うことがステップすることはできますか?

+0

サイズは同じですが長さはどうですか? minmalサンプルケースを追加しますか? – Divakar

+0

私は、forループの前と後の両方にm1.shape = 125,30,360を意味します。しかし、m1内の配列はサイズが変わります。例えば、m1 [10,10,10]が長さ5を有し、m2 [10,10,10]が長さ7をforループの前に有する場合、結果のm1 [10,10,10]は長さ12を有するこれが私の意図したことを明確にすることを願っています。 – Erik

+0

なぜ 'm1'はリストではなく3dオブジェクトのdtype配列ですか? ( 'arrayer'のタイプミスを修正してください) – hpaulj

答えて

0
In [164]: m1 = np.zeros([2, 2], dtype=np.ndarray) 
    ...: m2 = np.zeros([2, 2], dtype=np.ndarray) 
    ...: for i in range(2): 
    ...:  for j in range(2): 
    ...:   m1[i, j] = np.array(range(i+j)) 
    ...:   m2[i, j] = np.array(range(i+j+1)) 
    ...:   

結果は、dtypeオブジェクトの2つの2d配列です。 dtype=np.ndarraydtypesの定義されたセットに含まれないものについてはobjectになります。

In [165]: m1 
Out[165]: 
array([[array([], dtype=float64), array([0])], 
     [array([0]), array([0, 1])]], dtype=object) 
In [166]: m1.shape 
Out[166]: (2, 2) 
In [167]: m2.shape 
Out[167]: (2, 2) 
In [168]: m1[0,0] 
Out[168]: array([], dtype=float64) 
m1

次いで他所メモリ内のオブジェクトへのポインタを含む2Dアレイです。あなたの場合、それらは配列ですが、リスト、辞書、None、文字列または数字、または関数であってもかまいません。

このような配列は形状(2d)を持ち、形状変更が可能であり、場合によっては数学演算を要素(例:m1*2)まで投影することができるため、栄光のリストとして説明することができます。または、それはappendのようなメソッドを持っていないので、それはdebasedリストかもしれません。

このような配列での操作は、ほとんどの場合、Pythonレベルの反復処理が必要です(numpy)。そして、二重ループ、または同等のものを必要とする2次元形状。

nd配列と同じように、フラット化したネストループを回避することができます。リスト内包して例えば:

In [173]: [np.concatenate((a,b)) for a,b in zip(m1.flat, m2.flat)] 
Out[173]: [array([ 0.]), array([0, 0, 1]), array([0, 0, 1]), array([0, 1, 0, 1, 2])] 
In [174]: np.array([np.concatenate((a,b)) for a,b in zip(m1.flat, m2.flat)]).reshape(2,2) 
Out[174]: 
array([[array([ 0.]), array([0, 0, 1])], 
     [array([0, 0, 1]), array([0, 1, 0, 1, 2])]], dtype=object) 

これはfrompyfuncがあなたのために、より高次元の世話をして、有用である可能性の場合です。 、オブジェクト配列上の任意の要素ごとの操作がND数値で同様の操作に比べて遅くなります合計で

In [177]: f=np.frompyfunc(lambda a,b: np.concatenate((a,b)),2,1) 
In [178]: f(m1,m2) 
Out[178]: 
array([[array([ 0.]), array([0, 0, 1])], 
     [array([0, 0, 1]), array([0, 1, 0, 1, 2])]], dtype=object) 

:私はそれをより明示的なループをスピードアップ(最大で2倍)ささやかなを提供することを発見しましたアレイ。

+0

この回答をありがとう。本当によく説明されています。私の場合、入れ子のループはforループよりも5倍以上速く、frompyfuncは時間を節約しませんでした。 – Erik

関連する問題