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

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

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

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

Python

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

Q&A

解決済

1回答

6578閲覧

[numpy]一次元配列同士の行列同士の積の仕組みがわからない

loreeeee

総合スコア40

NumPy

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

Python

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

0グッド

0クリップ

投稿2020/08/03 14:49

前提・実現したいこと

以下のコードは6✖️1行の行列と1✖️3の行列の積を計算する意図で書いたプログラムです。
ab_result2の行で一応計算はできましたが、正直可読性がいまいちで簡潔に描きたいと思っています。
できればab_result1のように簡潔に表記したいのですが、なぜかvalue errorと表示されます。

このvalue errorはなぜ発生するのでしょうか?
また、一次元配列同士の積はどのように書くのが可読性のよい記述になるのでしょうか?

質問とはそれますが、
print(a.shape)で表示される(6,)は6行✖️1の配列という意味であっていますか?
(形状(6,1)が(6,)とデフォルトで表記されてしまっているという理解であってますか?)

import numpy as np a = np.array([1,2,3,4,5,6]) b = np.array([100,200,300]) print(a.shape) #(6,) ←これは6行✖️1の意味であってますか?((6,1)と同じ意味?) print(b.shape) #(3,) ab_result1 = a* b.T #6✖️1行の行列と1✖️3の行列の計算だがなぜこれでエラーがでるのか ab_result2 = a.reshape(a.shape[0],1) * b.reshape(1,b.shape[0]) print(ab_result1) print(ab_result2) #出力 ValueError: operands could not be broadcast together with shapes (6,) (3,) [ 100 200 300] [ 200 400 600] [ 300 600 900] [ 400 800 1200] [ 500 1000 1500] [ 600 1200 1800]]

補足情報(FW/ツールのバージョンなど)

python3.7

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

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

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

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

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

guest

回答1

0

ベストアンサー

print(a.shape) #(6,) ←これは6行✖️1の意味であってますか?

違います。1次元配列は縦ベクトル、横ベクトルといった区別がないので、
1次元配列を縦ベクトルとして扱いたい場合は a.reshape(-1, 1)、横ベクトルとして扱いたい場合は b.reshape(1, -1) と2次元配列に形状を変更する必要があります。

ちなみに * は要素同士の積なので、行列積を計算する場合の演算子は @ です。

python

1import numpy as np 2 3a = np.array([1, 2, 3, 4, 5, 6]) 4b = np.array([100, 200, 300]) 5 6# (6, 1) x (1, 6) 7c = a.reshape(-1, 1) @ b.reshape(1, -1) 8# c = a[:, np.newaxis] @ b[np.newaxis] でも同じ 9 10 11print(c) 12# [[ 100 200 300] 13# [ 200 400 600] 14# [ 300 600 900] 15# [ 400 800 1200] 16# [ 500 1000 1500] 17# [ 600 1200 1800]]

a.reshape(-1, 1) * b.reshape(1, -1) で同じ結果が計算できた理由

python

1[[1] 2 [2] 3 [3] 4 [4] 5 [5] 6 [6]]

python

1[[100 200 300]]

を演算しようとしたときにブロードキャストされて、

python

1[[1, 1, 1], 2 [2, 2, 2], 3 [3, 3, 3], 4 [4, 4, 4], 5 [5, 5, 5], 6 [6, 6, 6]]

python

1array([[100, 200, 300], 2 [100, 200, 300], 3 [100, 200, 300], 4 [100, 200, 300], 5 [100, 200, 300], 6 [100, 200, 300]])

の要素同士の積になって、たまたま行列積と同じ結果になりました。

投稿2020/08/03 17:04

編集2020/08/03 17:12
tiitoi

総合スコア21956

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

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

loreeeee

2020/08/03 23:20

ご回答ありがとうございます。1次元配列は縦ベクトル、横ベクトルといった区別がないことを知ることができ勉強になりました。 a.reshape(a.shape[0],1)はa.reshape(-1,1)のほうが簡潔な表記ですね。教えていただきありがとうございます。 行列の積に@演算子があることも知りませんでした。ブロードキャストの挙動は直感的に把握しにくいので質問の例だと@を使うほうが推奨されるのでしょうか?
tiitoi

2020/08/04 03:34

行列積は * では計算できません。今回縦ベクトルx横ベクトルという特殊な状況だったからたまたま行列積と同じ結果になっただけです。 行列積は @ 演算子で計算します。
loreeeee

2020/08/04 04:45

ありがとうございます。行列積と要素同士の掛け算の違いを意識しながら使い分けられるよう精進します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問