2

NumPy でこれらの種類の操作をベクトル化する一般的な方法はありますか?

In [2]: N = 8

In [3]: ll = np.arange(8)

In [4]: arr = np.zeros(ll.shape + (2, 2))

In [5]: ll.shape
Out[5]: (8,)

In [6]: arr.shape
Out[6]: (8, 2, 2)

In [7]: for ii in range(N):
   ...:     arr[ii, :, :] = np.array(...)  # 2 x 2 array function of ll[ii]

その関数が ll の線形演算である場合、これは簡単ですが、一般的なケースでそれを行う方法はありますか? 例を挙げると:

In [8]: for ii in range(N):
   ...:     arr[ii, :, :] = np.array([
   ...:         [np.cos(ll[ii]) - 1, 0],
   ...:         [np.sin(ll[ii]), np.cos(ll[ii]) ** 2]
   ...:     ])
4

2 に答える 2

5

arr配列を組み立てる正しい方法は次のようになります。

arr[:, 0, 0] = np.cos(ll) - 1
arr[:, 0, 1] = 0
arr[:, 1, 0] = np.sin(ll)
arr[:, 1, 1] = np.cos(ll) ** 2

np.array既存の配列に格納される予定の配列のリストを呼び出すべきではありません。これは無駄な中間配列の作成であり、悪い習慣であり、コードに明確さが追加されるとは思えません。メモリ/パフォーマンスを意識した開発者は、おそらく次のようなことをするでしょう:

np.cos(ll, out=arr[:, 0, 0])
arr[:, 1, 1] = arr[:, 0, 0]
arr[:, 0, 0] -= 1
arr[:, 0, 1] = 0
np.sin(ll, out=arr[:, 1, 0])
arr[:, 1, 1] *= arr[:, 1, 1]

しかし、これは多くの場合、時期尚早の最適化のカテゴリに分類されます。

llまた、変数名として使用しないでください...

于 2013-07-11T13:42:02.737 に答える
1

次のように実行できます。

def func(x):
    return np.array([
        [np.cos(x)-1,np.repeat(0, len(x))],
        [np.sin(x), np.cos(x)**2]
    ])

次にfunc(x)、 shape の配列を返し(2, 2, 8)ます。でお好みの向きで取り出せますfunc(x).T

これxは が 1 次元の場合にのみ機能します。を使用して高次元の何かを解決できると思いますがnp.broadcast_arrays、現時点では正確にはわかりません。ただし、基本的なことは、配列を返したい場合cos、一部のセルのようにベクトル化された numpy 関数を使用できず、他のセルにリテラル スカラー (0 など) を入れることができないということです。入力配列から派生した形状を持つ配列でスカラー セルを埋める必要があります。

于 2013-07-11T07:48:59.090 に答える