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

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

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

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

519閲覧

numpyでの複数のベクトルを結合させた1次元ベクトルと行列の積

aaa_ytooooo

総合スコア16

NumPy

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2020/04/25 10:23

Python3でnumpyを用いて計算したいと思っております。複数のベクトルを1つのベクトルにして,行列ベクトル積を計算したいと思っております。

#任意の自然数n,m,kで考えたいです n = 3 m = 5 k = 7 A = np.random.rand(m, n) data = np.random.rand(k * n) result = np.empty(k * m) for i in range(k): result[m*i:m*(i+1)] = np.dot(A, data[n*i:n*(i+1)])

一応結果は得られていますが,kが大きくなると時間がかかってしまいます。for文を使わずに高速で計算させる方法はありませんでしょうか?

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

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

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

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

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

guest

回答2

0

ベストアンサー

python

1import time 2import numpy as np 3 4np.random.seed(0) 5n = 3 6m = 5 7k = 7 8A = np.random.rand(m, n) 9A_t = A.T # Aは小さいのでこっちの転置でやることにする 10# 転置は一般に遅いことに注意。http://kaisk.hatenadiary.com/entry/2015/02/19/224531 11data = np.random.rand(k * n) 12data_m = data.reshape(k, n) # reshapeは速いはず 13 14result = (data_m @ A_t).ravel() # @で行列積取ってravelも速いはず 15 16# ------------------------------------------------------- 17# 以下オリジナルとの比較 18result_origin = np.empty(k * m) 19for i in range(k): 20 result_origin[m*i:m*(i+1)] = np.dot(A, data[n*i:n*(i+1)]) 21 22assert np.allclose(result_origin, result) # 結果の一致。厳密に一致しませんでした(なんでだろ) 23 24# 速度比較 25n = 3 26m = 5 27k = 10 ** 6 28A = np.random.rand(m, n) 29A_t = A.T 30data = np.random.rand(k * n) 31data_m = data.reshape(k, n) 32 33t1 = time.time() 34result_origin = np.empty(k * m) 35for i in range(k): 36 result_origin[m*i:m*(i+1)] = np.dot(A, data[n*i:n*(i+1)]) 37t2 = time.time() 38print(t2 - t1) # 4.4041972160339355 39 40t1 = time.time() 41result = (data_m @ A_t).ravel() 42t2 = time.time() 43print(t2 - t1) # 0.2488088607788086 44 45

投稿2020/04/25 11:54

編集2020/04/25 12:10
hayataka2049

総合スコア30933

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

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

aaa_ytooooo

2020/04/25 12:20

回答いただきありがとうございます。実際に時間まで測定していただきありがとうございます。行列積を@で計算できることを初めて知りました。@演算子とnumpy.dotはどちらの方が高速かご存知でしょうか?
hayataka2049

2020/04/25 12:22 編集

その2つはほぼ差はないはずです。インターフェースの違いはありますが。
aaa_ytooooo

2020/04/25 12:29

回答ありがとうございます。参考にさせていただきます。
hayataka2049

2020/04/25 12:37

元コードだと result_origin[m*i:m*(i+1)] = np.dot(A, data[n*i:n*(i+1)]) をk回やるのが遅く、これを単一の行列積演算にしてしまえればそれ以外は何でもいいと言えます。segavvyさんの回答も考え方は同じです(一応こちらの方が多少速いというつもりで回答しましたが、測ってみたら数割違うかなという程度っぽいです)。
hayataka2049

2020/04/25 12:48

コメントでは約0.25秒になってますが、平均取ったら数倍くらい速かったです。たまたまバックグラウンドプロセスとかで遅くなったのを引いたみたい。
guest

0

result = np.dot(A, data.reshape([k, n]).T).T.reshape([-1])

でどうでしょうか。
もう少しシンプルに書けるかもしれませんが……

投稿2020/04/25 10:55

編集2020/04/25 10:56
segavvy

総合スコア958

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

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

aaa_ytooooo

2020/04/25 11:45

回答いただきありがとうございます! やはり一度行列に直してから計算した方がよさそうですね。参考にさせていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問