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

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

新規登録して質問してみよう
ただいま回答率
85.48%
NumPy

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

Python

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

Q&A

2回答

5326閲覧

NumPy配列のドット積について

退会済みユーザー

退会済みユーザー

総合スコア0

NumPy

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

Python

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

0グッド

0クリップ

投稿2017/11/27 23:54

編集2017/11/27 23:56

いつも大変お世話になっております。

NumPy配列のドット積について、以下をご覧ください。

![イメージ説明
2 x 2 どうしの場合は、
このように
A横(1と2) x B縦(5と7)   *つまり、横x縦
と計算できるはずですが、

イメージ説明
3 x 2 と 1 x 2 の場合は、
A横(1と2) x B縦(7と?)
とはならず、どうして
A横(1と2) x B横(7と8)  *つまり、横x横
となるのでしょうか?

どなたか教えて頂けますと大変助かります。

以上、宜しくお願い申し上げます。

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

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

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

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

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

quickquip

2017/11/28 00:46

コードを質問に書きましょう。あなたがなにをやったのか、そしてどうなったのかが分からないせいで混乱しています。
guest

回答2

0

まず、質問文に貼ってある画像は行列積であって、今回の話と全く関係ない演算です。

なので

2 x 2 どうしの場合は、

このように
A横(1と2) x B縦(5と7)   *つまり、横x縦
と計算できるはずですが、

ここからしてもう違います。

A*Bであれば、ndarray同士の掛け算で、基本的にはインデックスが同じ位置同士で掛け算をします。
ですから、各次元の要素数が一致してないと本来は演算できないんですが、
ブロードキャストというものが可能である場合は演算できます。

今回の場合だとB
np.array([[7,8],[7,8],[7,8]])と拡張されたものとして計算されてます

ブロードキャストの解説:
NumPyのブロードキャストのメリットと解説

np.dot(A,B)であれば、A,Bが両方二次元のndarrayだったらたしかに行列積になるのですが、
今回はそうではないのでKSwordOfHasteさんの回答のとおりになります。

投稿2017/11/28 00:38

編集2017/11/28 01:13
ozwk

総合スコア13521

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

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

KSwordOfHaste

2017/11/28 00:43

あ・・・dotじゃなく*でしたか;;; 質問文をみたときの注意不足でした。
ozwk

2017/11/28 00:46 編集

いや、これ書いた後ドット積と書いてあるのに気づいて *じゃなくてdotだったかと思っているところです
KSwordOfHaste

2017/11/28 00:47

どっちが本当なのかわからなくなりましたw;
KSwordOfHaste

2017/11/28 01:26

自分は ・次元があってたら要素ごとに演算 ・多次元配列と1要素の演算もできる という程度の認識しかなく、その仕様が自然におもえたのでなんの疑問もなく使っていました。ozwkさん回答でNumpyのブロードキャストという用語を知ったのですが用語を知っておくのはとても重要なので大変参考になりました。ありがとうございました。
guest

0

np.array([7, 8])のshapeは(1, 2)ではなく(2,)ですよ?

数学的に行列A,Bのドット積 A . Bは、A,Bの次元が

A.shape == (a1, a2, a3, ..., aN)
B.shape == (b1, b2, b3, ..., bM)

であったとき、aN == b1のときに定義されます。

ご質問の場合

A.shape == (3, 2)
B.shape == (2,)

ですのでこうなることに不思議はないのです。


補足:
b = np.array([[7, 8]])
と書くと、shapeは(1, 2)になります。これを第二引数に指定すると質問者さんがおっしゃるとおりの計算をすることになり、aN != b1になるためエラーが起きます。

投稿2017/11/28 00:12

編集2017/11/28 00:23
KSwordOfHaste

総合スコア18394

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

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

ozwk

2017/11/28 00:28

> 補足 エラー起きませんでしたよ?
KSwordOfHaste

2017/11/28 00:33 編集

>>> a=np.array([[1,2],[3,4],[4,5]]) >>> a array([[1, 2], [3, 4], [4, 5]]) >>> b=np.array([[7,8]]) >>> np.dot(a,b) Traceback (most recent call last): File "<pyshell#3>", line 1, in <module> np.dot(a,b) ValueError: shapes (3,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0) こうなりました。python3.6.0です。バージョンによってはbの最初の次元が1だったらなかったことにしてくれるといった振る舞いをしたりするんでしょうか!?使いやすさのためそういう振る舞いをしてくれる配列演算機能を何かで見た気がします(別言語ですが)
KSwordOfHaste

2017/11/28 00:38

失礼しました。numpyのバージョンを書くべきでしたね。自分の環境では numpy 1.12.1+mkl でした。
KSwordOfHaste

2017/11/28 00:44

ozwkさんの回答みてようやく気付きました。dot積じゃなくてcross積ですね・・・
KSwordOfHaste

2017/11/28 01:22

質問者さんが混乱しないようにコメントしておきます。 行列演算での積の代表的なものにdot積、cross積があります。自分の回答はdot積についてのものです。 Numpyを使う場合、ozwkさん回答にあるブロードキャストについても知っておく必要があると思います。これを知っておくと行列演算がより理解できると思いますが知らないと混乱の元になると思いました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問