Numpy:各行をベクトル要素で除算します


119

私が派手な配列を持っているとしましょう:

data = np.array([[1,1,1],[2,2,2],[3,3,3]])

対応する「ベクター」があります。

vector = np.array([1,2,3])

data各行に沿って操作して減算または除算を行うと、結果は次のようになります。

sub_result = [[0,0,0], [0,0,0], [0,0,0]]
div_result = [[1,1,1], [1,1,1], [1,1,1]]

簡単に言うと、2D配列の各行に対して、各行に対応するスカラーの1D配列で演算を実行するにはどうすればよいですか?

回答:


181

どうぞ。ブロードキャストと組み合わせて使用する必要がありますNone(または代わりにnp.newaxis):

In [6]: data - vector[:,None]
Out[6]:
array([[0, 0, 0],
       [0, 0, 0],
       [0, 0, 0]])

In [7]: data / vector[:,None]
Out[7]:
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

13
ここにドキュメントがあります。
サザリ2015


numpyの最新バージョン(1.18.1)を使用する@ user108569は、None引き続きと同等に機能しnp.newaxisます。私はあなたのセットアップが何であるか、またはあなたが経験している正確な問題を知りませんが、答えはまだ有効です。
JoshAdel

11

すでに述べたように、with Noneまたはwith を使用したスライスnp.newaxesは、これを行うための優れた方法です。別の選択肢は、次のようにトランスポーズとブロードキャストを使用することです

(data.T - vector).T

そして

(data.T / vector).T

より高次元の配列の場合はswapaxes、NumPy配列のメソッドまたはNumPy rollaxis関数を使用できます。これを行う方法は本当にたくさんあります。

ブロードキャストの詳細については、http://docs.scipy.org/doc/numpy/user/basics.broadcasting.htmlを参照してください。


4

JoshAdelのソリューションは、np.newaxisを使用して次元を追加します。代わりの方法は、reshape()を使用して、ブロードキャストの準備として次元を揃えることです。

data = np.array([[1,1,1],[2,2,2],[3,3,3]])
vector = np.array([1,2,3])

data
# array([[1, 1, 1],
#        [2, 2, 2],
#        [3, 3, 3]])
vector
# array([1, 2, 3])

data.shape
# (3, 3)
vector.shape
# (3,)

data / vector.reshape((3,1))
# array([[1, 1, 1],
#        [1, 1, 1],
#        [1, 1, 1]])

reshape()を実行すると、ディメンションをブロードキャストに合わせることができます。

data:            3 x 3
vector:              3
vector reshaped: 3 x 1

それdata/vectorは大丈夫ですが、あなたが望む答えを得られないことに注意してください。(各行ではarrayなく)の各を、の対応する各要素で除算しますvector。の代わりに明示的に再形成vectorした場合に得られるものです。1x33x1

data / vector
# array([[1, 0, 0],
#        [2, 1, 0],
#        [3, 1, 1]])
data / vector.reshape((1,3))
# array([[1, 0, 0],
#        [2, 1, 0],
#        [3, 1, 1]])

2

これを行うPythonicの方法は...

np.divide(data.T,vector).T

これにより、形状変更が行われ、結果は浮動小数点形式になります。他の回答では、結果は丸められた整数形式です。

#注:データとベクトルの両方の列が一致する必要があります


注:これは、OPが要求することを行いません。最終結果はarray([[1。、0.5、0.33333333]、[2.、1.、0.66666667]、[3.、1.5、1.]])です。「Pythonic」かもしれませんが、正しくありません。
Mark Cramer

1
@MarkCramerありがとうございます。正しい結果が得られるように回答を修正しました。
shantanu pathak

1

stackoverflowuser2010の回答に追加して、一般的なケースでは単に使用できます

data = np.array([[1,1,1],[2,2,2],[3,3,3]])

vector = np.array([1,2,3])

data / vector.reshape(-1,1)

これにより、ベクターがに変わりますcolumn matrix/vector。必要に応じて要素ごとの操作を実行できます。少なくとも私にとっては、これは最も直感的な方法であり、(ほとんどの場合)numpyは同じ内部メモリのビューを使用して再形成するだけなので、効率的でもあります。


これは受け入れられる答えになるはずです。で列ベクトルを作成すること.reshape(-1,1) は、ブロードキャストを使用する最も直感的な方法です。
Paul Rougieux
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.