任意の行列の各行に行列を乗算

how to multiply a matrix with every row in another matrix using numpy – StackOverflow

悩んだときのアインシュタイン記法.

import numpy as np


a = np.array(
    [
        [0, 1, 1],
        [2, 2, 0],
        [3, 0, 3]
    ]
)

b = np.array(
    [
        [1, 1, 1],
        [2, 2, 2],
        [3, 2, 9],
        [4, 4, 4],
        [5, 9, 5]
    ]
)

np.einsum('ij,kj->ik', b, a) # b @ a.T
array([[ 2,  4,  6],
       [ 4,  8, 12],
       [11, 10, 36],
       [ 8, 16, 24],
       [14, 28, 30]])

効率は極めて悪いが,ブロードキャストを用いると分かり易い.

(a * b[:, None]).sum(-1)
array([[ 2,  4,  6],
       [ 4,  8, 12],
       [11, 10, 36],
       [ 8, 16, 24],
       [14, 28, 30]])
a = np.random.randint(0, 1000, (3000, 3))
b = np.random.randint(0, 1000, (10000, 3))
%timeit b @ a.T
%timeit np.einsum('ij,kj->ik', b, a)
%timeit np.einsum('ij,jk->ik', b, a.T)
%timeit np.einsum('ij,kij->ki', a, b[:, None])
%timeit np.einsum('ij,kj->ik', b, a, optimize=True)
%timeit np.einsum('ij,jk->ik', b, a.T, optimize=True)
%timeit np.einsum('ij,kij->ki', a, b[:, None], optimize=True)
%timeit (a * b[:, None]).sum(-1)
10 loops, best of 3: 132 ms per loop
1 loop, best of 3: 204 ms per loop
1 loop, best of 3: 192 ms per loop
10 loops, best of 3: 198 ms per loop
10 loops, best of 3: 182 ms per loop
10 loops, best of 3: 183 ms per loop
1 loop, best of 3: 206 ms per loop
1 loop, best of 3: 861 ms per loop
カテゴリー: 未分類 パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください