以下のaとbのように、それぞれ配列(ベクトル)が複数格納されたデータがあり、この配列同士の全組み合わせに対し、別の関数で定義した配列演算をしたいと思っています(この場合、決定係数という統計指標の算出を使っています)。
この時、for文を二つ回さずに実行する方法を教えていただけないでしょうか?
np.meshgridを使おうとしたのですが、なかなかうまくいかず、止まっています。
Python
1import numpy as np 2 3def calc(x,y): 4 return 1 - sum((x - y) ** 2) / sum((x - y.mean()) ** 2) 5 6a = np.array([[0, 0, 0, 0, ], [5, 5, 5, 10], [1, 2, 10, 12], [-3, 0, -2, 12]]) 7b = np.array([[1, 2, 3, 4, ], [8, 0, 10, 22], [5, 6, 7, 0], [-1, 0, 10, -12]]) 8 9# 以下は計算可能だが、aとbの全配列組み合わせで実施したい(a[0]〜a[3]×b[0]〜b[3]のイメージ) 10calc(a[0], b[1])
なぜ、for文をふたつ回さずに実行したいのですか。
他の書き方を使っても、性能的に早くなることはありません。
性能以外の原因があるのでしょうか?
ありがとうございます。センサーからあがってくるデータに対して、この計算をリアルタイムで逐次処理しなければならないため、性能が必要です。
以下のリンクにあるように、for文を使わないと早いという文言を見て「for文使わない方がいいだろうな」と考え、meshgirdでの実装を考えていました。ご指摘のとおり、他の方法で早くならなければ、目的は達成できません。
https://sekailab.com/wp/2018/06/11/numpy-combinatorial-calculation-in-array/
>他の書き方を使っても、性能的に早くなることはありません。
このリンクではfor文を回さず、meshgirdで実行した方が早いとありますが、そうならない、ということでしょうか?for文で処理せず、numpyで可能な限り一括計算に持ち込んで処理することで、処理性能は向上するものばかりと思っていましたが、、、。
pythonのfor文が非常に遅いのは間違いありません。長さ4の二重ループを使うと、イテレータの呼び出しが25回、割り込みが5回起こるので、それだけでも膨大な時間がかかります。
これを回避するために、多次元配列の計算部分をC言語やアセンブラで書かれた高速なライブラリを呼び出すのがnumpyの役目です。
meshgridが使えるのであれば良いのですが、meshgridを使うのはほぼ確実に無理です。calc関数自体を変更せずにほかの制御方法を使った場合には性能は変わりません。
meg_の回答のように、calc関数をnumpyを使って書き直すのはかなり良い方法です。明示的な関数呼び出しだけでなく、**演算や/演算もC言語やアセンブラで書かれた関数の呼び出しになるので、かなりの高速化が期待できます。
性能が不足する場合は、numpyにリンクされているblasライブラリを有償のものに取り換えると、SIMD命令を有効利用することで性能が上がります。
それでも性能が不足するようでしたら、calc関数をpythonインタフェースを使ったC言語で作ることになりますが、ご自身で行うことはお勧めしません。
承知しました。ありがとうございます!
回答3件
あなたの回答
tips
プレビュー