質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

1978閲覧

python numpyで3×3行列とベクトルの配列にたいして内積を行いたい

kyte_tsuboyama

総合スコア5

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

0クリップ

投稿2020/03/24 00:32

前提・実現したいこと

python3.7 numpyを使用して、行列の配列に対して内積をしたいと考えております。
行列は、
A[3][3][x]
B[3][x]
xは数千程度で、
A[3][3]・B[3]の結果をx分格納した結果を取得したいのですが、
numpyのdot積分を使用して、
np.dot(A,B.T)
と記述すると、思った結果が得られないという状況です。

例として、次のようなコードを書いた場合に
a = np.asarray([[[1, 2 , 3], [4, 5, 6], [7, 8, 9]]
, [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
, [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
, [[1, 2, 3], [4, 5, 6], [7, 8, 9]]])
b = np.asarray([[1, 0, 0],[2, 0, 0], [3, 0, 0], [4, 0, 0]])
c = np.dot(a, b.T)
print(c)
求める結果は
[[ 1 4 7]
[ 2 8 14]
[ 3 12 21]
[ 4 16 28]]
なのですが、実際の出力は、
[[[ 1 2 3 4]
[ 4 8 12 16]
[ 7 14 21 28]]

[[ 1 2 3 4]
[ 4 8 12 16]
[ 7 14 21 28]]

[[ 1 2 3 4]
[ 4 8 12 16]
[ 7 14 21 28]]

[[ 1 2 3 4]
[ 4 8 12 16]
[ 7 14 21 28]]]
となります。

これを解決するために、
c = np.empty([b.shape[0],b.shape[1]])
for i in range(b.shape[0]):
buf = b[i]
c[i] = np.dot(a[i],buf.T)
print(c)
としたところ、
[[ 1. 4. 7.]
[ 2. 8. 14.]
[ 3. 12. 21.]
[ 4. 16. 28.]]
となり、求める結果を得ることはできました。

しかし、せっかくnumpyを使用しているのに、for文で回しているので、
for文を使わずに、もっといい書き方があれば、ご教授いただければと思います。

宜しくお願いいたします。

magichan👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

python

1a = np.array([[[1, 2, 3], [4, 5, 6], [7, 8, 9]], 2 [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 3 [[1, 2, 3], [4, 5, 6], [7, 8, 9]], 4 [[1, 2, 3], [4, 5, 6], [7, 8, 9]]]) 5b = np.array([[1, 0, 0], [2, 0, 0], [3, 0, 0], [4, 0, 0]]) 6 7c = (a*b[:,None,:]).sum(2) 8print(c) 9# [[ 1 4 7] 10# [ 2 8 14] 11# [ 3 12 21] 12# [ 4 16 28]] 13 14c = np.einsum('ijk,ik->ij', a, b) 15print(c) 16# [[ 1 4 7] 17# [ 2 8 14] 18# [ 3 12 21] 19# [ 4 16 28]]

ということですか?

英語ですが、以下のサイトが参考になります。
A basic introduction to NumPy's einsum – ajcr – Haphazard investigations


python

1""" 2i = 第0軸 3j = 第1軸 4k = 第2軸 5""" 6----- a ----- 7 j 0 1 2 8i k 0 1 2 90 #[[[1 2 3] [4 5 6] [7 8 9]] 101 # [[1 2 3] [4 5 6] [7 8 9]] 112 # [[1 2 3] [4 5 6] [7 8 9]] 123 # [[1 2 3] [4 5 6] [7 8 9]]] 13 14----- b ----- 15 j 0 1 2 16i k 0 1 2 170 #[ [1 0 0] 181 # [2 0 0] 192 # [3 0 0] 203 # [4 0 0] ] 21 22""" 23A{i, j, k} と B{i, j, k} を要素ごとに掛け算したい。 24Bには [i,j,k] の3軸のうち、真ん中の軸が欠けている。 25→→Bの2軸の間にj軸を追加すると以下のようになる 26""" 27----- b[:,None,:] ----- 28 j 0 1 2 29i k 0 1 2 300 #[[[1 0 0] [ > ] [ > ]] 311 # [[2 0 0] [ > ] [ > ]] 322 # [[3 0 0] [ > ] [ > ]] 333 # [[4 0 0] [ > ] [ > ]]] 34 35""" 36k(第2軸)を総計して潰すので、sum(axis=2) 37""" 38----- (a*b[:, None, :]).sum(2) ----- 39 j 0 1 2 40i k - 410 # [[ 1 4 7] 421 # [ 2 8 14] 432 # [ 3 12 21] 443 # [ 4 16 28]]

投稿2020/03/24 04:11

編集2020/03/24 05:29
kirara0048

総合スコア1399

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kyte_tsuboyama

2020/03/24 13:00

j軸がかけている分を追加する必要があったのですね。 とても参考になりました、ありがとうございました。 アインシュタインの縮約記法はちょっと難しかったので、 勉強してみたいと思います。
guest

0

python

1 x = map(lambda x: list(np.dot(a,x)[0]), b) 2 print(list(x))

速度が向上するかわかりませんが、例えばmapを利用する例です。

投稿2020/03/24 03:56

t_obara

総合スコア5488

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問