15

2Dnumpy配列が与えられた場合、すべての列とそれ自体の内積を計算し、結果を 1D 配列に格納する必要があります。以下の作品:

In [45]: A = np.array([[1,2,3,4],[5,6,7,8]])

In [46]: np.array([np.dot(A[:,i], A[:,i]) for i in xrange(A.shape[1])])
Out[46]: array([26, 40, 58, 80])

Python ループを回避する簡単な方法はありますか? 上記は世界の終わりではありませんが、numpyこれに対するプリミティブがあれば、それを使用したいと思います。

edit実際には、マトリックスには多くの行と比較的少数の列があります。したがって、私は一時配列よりも大きな一時配列を作成することにあまり熱心ではありませんO(A.shape[1])。また、その場で変更することもできませんA

4

3 に答える 3

21

どうですか:

>>> A = np.array([[1,2,3,4],[5,6,7,8]])
>>> (A*A).sum(axis=0)
array([26, 40, 58, 80])

編集:うーん、わかりました、中間の大きなオブジェクトは必要ありません。多分:

>>> from numpy.core.umath_tests import inner1d
>>> A = np.array([[1,2,3,4],[5,6,7,8]])
>>> inner1d(A.T, A.T)
array([26, 40, 58, 80])

とにかく少し速いようです。AT はビュー (独自のコピー、IIUC を作成しない) であり、inner1d は必要な方法でループするように見えるため、これは舞台裏で必要なことを行う必要があります。

非常に遅れた更新:別の代替手段は、次を使用することnp.einsumです:

>>> A = np.array([[1,2,3,4],[5,6,7,8]])
>>> np.einsum('ij,ij->j', A, A)
array([26, 40, 58, 80])
>>> timeit np.einsum('ij,ij->j', A, A)
100000 loops, best of 3: 3.65 us per loop
>>> timeit inner1d(A.T, A.T)
100000 loops, best of 3: 5.02 us per loop
>>> A = np.random.randint(0, 100, (2, 100000))
>>> timeit np.einsum('ij,ij->j', A, A)
1000 loops, best of 3: 363 us per loop
>>> timeit inner1d(A.T, A.T)
1000 loops, best of 3: 848 us per loop
>>> (np.einsum('ij,ij->j', A, A) == inner1d(A.T, A.T)).all()
True
于 2011-06-03T16:04:58.940 に答える
2

すべての要素の二乗を計算し、次を使用して列ごとに合計できます

np.sum(np.square(A),0);

sum(合計を取る軸を識別する関数の2番目のパラメーターについては完全にはわかりません。現在、numpyがインストールされていません。おそらく実験する必要があります:) ...)

編集

DSMの投稿を見ると、 を使用する必要があるようaxis=0です。関数を使用すると、 を使用するsquareよりも少しパフォーマンスが向上する場合がありますA*A

于 2011-06-03T16:05:20.010 に答える
0

線形代数から、行 i と行 j の内積は AA^T の i,j 番目のエントリです。同様に、列 i と列 j の内積は、(A^T)A の i,j 番目のエントリです。

したがって、 A の各列ベクトルとそれ自体の内積が必要な場合は、 を使用できますColDot = np.dot(np.transpose(A), A).diagonal()。一方、各行とそれ自体の内積が必要な場合は、 を使用できますRowDot = np.dot(A, np.transpose(A)).diagonal()

どちらの行も配列を返します。

于 2014-05-07T19:50:08.477 に答える