ブロードキャストを使用して多次元配列を計算する方法

How to calculate the multidimensional array with broadcasting? – StackOverflow

  • How to vectorize the array and calculate it with broadcasting?
import numpy as np


def loops(a, b, N, l):
    r = np.zeros((N, N, l))
    for i in range(N):
        for j in range(N):
            r[i,j]=a[i]*a[j]*(b[i]-b[j])-a[i]/a[j]
    return r


def broadcasts(a, b):
    return a[:, None] * a * (b[:, None]-b) - a[:, None] / a


def func(a, b):
    return np.einsum('ij, kj, ikj->ikj', a, a, b[:, None]-b, optimize=True) - a[:, None] / a


N, l = 200, 100
a = np.random.rand(N, l)
b = np.random.rand(N, l)

np.testing.assert_allclose(loops(a, b, N, l), broadcasts(a, b))
%timeit loops(a, b, N, l)
%timeit broadcasts(a, b)
np.testing.assert_allclose(broadcasts(a, b), func(a, b))
%timeit func(a, b)
1 loop, best of 3: 201 ms per loop
10 loops, best of 3: 43.9 ms per loop
10 loops, best of 3: 45.6 ms per loop
  • I also want to set the index inot equalsj, which means leave the diagonal element as zero. Can I do that also by vectorization?
import numpy as np


def loops(a, b, N, l):
    r = np.zeros((N, N, l))
    for i in range(N):
        for j in range(N):
            if i != j: r[i,j]=a[i]*a[j]*(b[i]-b[j])-a[i]/a[j]
    return r


def broadcasts(a, b, N):
    out = a[:, None] * a * (b[:, None]-b) - a[:, None] / a
    out[np.diag_indices(N)] = 0
    return out


def func(a, b, N):
    out = np.einsum('ij, kj, ikj->ikj', a, a, b[:, None]-b, optimize=True) - a[:, None] / a
    out[np.diag_indices(N)] = 0
    return out


N, l = 200, 100
a = np.random.rand(N, l)
b = np.random.rand(N, l)

np.testing.assert_allclose(loops(a, b, N, l), broadcasts(a, b, N))
%timeit loops(a, b, N, l)
%timeit broadcasts(a, b, N)
np.testing.assert_allclose(broadcasts(a, b, N), func(a, b, N))
%timeit func(a, b, N)
1 loop, best of 3: 200 ms per loop
10 loops, best of 3: 43.1 ms per loop
10 loops, best of 3: 45.1 ms per loop
カテゴリー: 未分類 パーマリンク

コメントを残す

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

WordPress.com ロゴ

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

Google フォト

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

Twitter 画像

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

Facebook の写真

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

%s と連携中

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