

以下の計算を高速で行う方法を教えていただきたいです．

[code]

    import numpy as np
    # 本当は10万くらいの長さ
    a = np.array([[1,2,3],[4,5,6]])
    # こっちも10万くらいの長さ
    b = np.array([ [ [1,2,3],[4,5,6],[7,8,9] ], [ [1,2,3],[4,5,6],[7,8,9] ] ])
    res = []
    for i in range(a.shape[0]):
        for j in range(b.shape[0]):
            c = np.dot(a[i],b[i,j])
            res.append(c)
    
[/code]

ベクトルが格納された配列（行列）と行列が格納された配列（三次テンソル）の積を上記のようなfor文を利用せず高速に計算する方法がありましたら，教えていただきたいです．


CC BY-SA 4.0
2019-03-21T12:32:29.260
53626
2019-03-24T14:00:22.017
2019-03-24T14:00:22.017
32624
32624
question
python python3 numpy
ベクトルと行列の高速計算


multiprocessingを使って、一番内側のforループの処理を並列化すれば、処理速度は向上すると思います。

並列化すると、どの順序で計算結果が返ってくるかが判らないので、

[code]

    res.append(c)
    
[/code]

だと、順序通りに入るかどうかが判りません。

配列resのどこに結果を入れるのかを指定するようなコードの工夫が必要かと思います。

[code]

    res[i*N + j] = np.dot(a[i],b[j])
    
[/code]


CC BY-SA 4.0
2019-03-22T05:34:31.537
53647
2019-03-22T05:34:31.537
217
53626
answer


pythonのfor文は遅いので、適切に高速化されている（はずの）numpyで処理したい、ということだと思います。

私はテンソルの計算は経験はないのですが、`numpy`にはテンソル積やテンソルのドット積を計算できる`numpy.tensordot`や、`numpy.einsum`があるので、うまく使うと簡単に書けたりしないでしょうか。

記載いただいたコードを見るとドット積を計算したいようなので、試してみました。（質問のコードが`IndexError`ーになるので確証はないのですが、以下で質問の意図に沿ってますかね？）。  
高速化できるかは実際に試してみていただければと。

[code]

    import numpy as np
    # 本当は10万くらいの長さ
    a = np.array([[1,2,3],[4,5,6]])
    # こっちも10万くらいの長さ
    b = np.array([ [ [1,2,3],[4,5,6],[7,8,9] ], [ [2,3,4],[5,6,7],[8,9,10] ] ])
    
    c = np.tensordot(a,b.T,1)
    x, y, z = c.shape
    
    tmp = c.reshape(1, x * y * z)
    res = tmp[0].tolist()
    
[/code]

なお、以下を参考にしました。

  * [NumPyによる数値計算の高速化 : 基礎 - Qiita](https://qiita.com/jabberwocky0139/items/c3620fb2f011f20a633b)
  * [Python - numpyでのベクトルと行列の積演算の一括処理｜teratail](https://teratail.com/questions/108783)

また、他の手段として、`dask`のような並列処理を利用できるライブラリを使ったり、`cupy`なりを使ってGPUで処理したりすると、高速化が図れるかもしれませんね。


CC BY-SA 4.0
2019-03-24T00:58:04.617
53680
2019-03-24T00:58:04.617
12561
53626
answer