2016-03-27 10 views
5

は観察:column_stackrow_stackについても同様なぜnumpy.broadcastはvstackなどの機能の結果を "転記"しますか?

In [1]: import numpy as np 
In [2]: x = np.array([1, 2, 3]) 
In [3]: np.vstack([x, x]) 
Out[3]: 
array([[1, 2, 3], 
     [1, 2, 3]]) 

In [4]: np.vstack(np.broadcast(x, x)) 
Out[4]: 
array([[1, 1], 
     [2, 2], 
     [3, 3]]) 

hstack、この場合に異なる動作が、放送に使用される場合、それはまた、異なります)。どうして?

私はこの振る舞いを「修復」する方法を見つけるよりも、その背後にあるロジックを守っています(私はそれでうまくいく、ちょうど直感的ではありません)。

答えて

5

np.broadcastは、を表すイテレータオブジェクトのインスタンスを返します。配列を一緒にブロードキャストする必要があります。 とりわけ、結果として得られる配列の形状と次元数を記述します。

極めて重要な、あなたは各入力配列から要素のタプルを取り戻すPythonで、このオブジェクトの上に、あなた実際に反復

>>> b = np.broadcast(x, x) 
>>> b.shape 
(3,) 
>>> b.ndim 
1 
>>> list(b) 
[(1, 1), (2, 2), (3, 3)] 

これは(私たちはアレイ上の実際の操作を実行している場合を教えてくれるx+x)NumPyは形状の配列(3,)を1次元返し、最終配列の値を生成するためにタプルの要素を結合します(例えば、加算の場合は1+12+23+3を実行します)。

あなたはall it doesはそれが与えられていることをイテラブルの要素は、少なくとも2次元であることを確認した後、軸に沿って0

それらを積み重ねることがわかりvstackのソースに掘る場合

>>> [np.atleast_2d(_m) for _m in b] 
[array([[1, 1]]), array([[2, 2]]), array([[3, 3]])] 

これら三つの小さな配列は、その後、垂直あなたが注意して出力を生成積層さ:b = np.broadcast(x, x)の場合、これは我々がスタックするには、次の配列を得ることを意味します。様々な大きさの配列を並列に反復処理されている正確にどのように


はどのようにnumpyのの放送作品の核心です。コードはほとんどがiterators.cにあります。 Travis Oliphant自身が書いたNumPyの多次元イテレータの興味深い概要は、Beautiful Codeの本にあります。

+0

np.concatenate(np.broadcast(...))がうまくいきません。 'vstack'(および親戚)が行うリストの理解が必要です。 'np.array(list(np.broadcast(...)))'は動作しますが、より高速です。 – hpaulj