9

2 つの配列aとがあるとしますb

  a.shape = (5,2,3)
  b.shape = (2,3)

次に、で形状c = a * bの配列を取得します。c(5,2,3)c[i,j,k] = a[i,j,k]*b[j,k]

今の状況は、

  a.shape = (5,2,3)
  b.shape = (2,3,8)

cで形に(5,2,3,8)したいc[i,j,k,l] = a[i,j,k]*b[j,k,l]

これを効率的に行うには?私aのとb実際にはかなり大きいです。

4

2 に答える 2

13

これは機能するはずです:

a[..., numpy.newaxis] * b[numpy.newaxis, ...]

使用法:

In : a = numpy.random.randn(5,2,3)

In : b = numpy.random.randn(2,3,8)

In : c = a[..., numpy.newaxis]*b[numpy.newaxis, ...]

In : c.shape
Out: (5, 2, 3, 8)

参照:numpyでのアレイブロードキャスト

編集:参照URLを更新

于 2012-05-20T22:37:00.830 に答える
7

私は以下がうまくいくはずだと思います:

import numpy as np
a = np.random.normal(size=(5,2,3))
b = np.random.normal(size=(2,3,8))
c = np.einsum('ijk,jkl->ijkl',a,b)

と:

In [5]: c.shape
Out[5]: (5, 2, 3, 8)

In [6]: a[0,0,1]*b[0,1,2]
Out[6]: -0.041308376453821738

In [7]: c[0,0,1,2]
Out[7]: -0.041308376453821738

np.einsum使用するのは少し難しいかもしれませんが、これらの種類のインデックス作成の問題に対して非常に強力です:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.einsum.html

また、これには numpy >= v1.6.0 が必要であることに注意してください

特定の問題の効率についてはわかりませんが、必要に応じて実行されない場合は、明示的な for ループで Cython を使用することを検討し、おそらく次を使用して並列化しますprange

アップデート

In [18]: %timeit np.einsum('ijk,jkl->ijkl',a,b)
100000 loops, best of 3: 4.78 us per loop

In [19]: %timeit a[..., np.newaxis]*b[np.newaxis, ...]
100000 loops, best of 3: 12.2 us per loop


In [20]: a = np.random.normal(size=(50,20,30))
In [21]: b = np.random.normal(size=(20,30,80))

In [22]: %timeit np.einsum('ijk,jkl->ijkl',a,b)
100 loops, best of 3: 16.6 ms per loop

In [23]: %timeit a[..., np.newaxis]*b[np.newaxis, ...]
100 loops, best of 3: 16.6 ms per loop

In [2]: a = np.random.normal(size=(500,20,30))
In [3]: b = np.random.normal(size=(20,30,800))

In [4]: %timeit np.einsum('ijk,jkl->ijkl',a,b)
1 loops, best of 3: 3.31 s per loop

In [5]: %timeit a[..., np.newaxis]*b[np.newaxis, ...]
1 loops, best of 3: 2.6 s per loop
于 2012-05-20T22:32:40.707 に答える