4

これが、Numpy行列の各要素に対して計算する必要のある式です。

Mi_j = Sum_v(Av * Xi_v) + Sum_v(Bv * Wj_v) + Sum_v(Gv * Zij_v)

私はそれを厄介な方法でコーディングする方法を本当に見ていません(Pythonでは長すぎます):vectorized / slicing /CApi。

何を提案しますか。簡単な例を教えてください。numpyは初めてです。

@編集されたインデックス

  • A、B、Gは1次元の配列です[x、x、x]
  • XiとWjについても同じです(Xは行列、Wは行列)
  • Zijは1次元の配列です
4

2 に答える 2

2

個人的には、代数プロセスを決定し、numpy 行列を使用して標準として実行する方が読みやすいと思います。あなたの作業が数学的なものである場合、numpymatrixクラスを使用すると、数学をコードに変換したり、その逆を行ったりするのがはるかに簡単になります。

これにより、慎重にブロードキャストする必要がなくなります。

で始まります:

Mi_j = Sum_v(Av * Xi_v) + Sum_v(Bv * Wj_v) + Sum_v(Gv * Zij_v)

numpy では次のようになります。

M = X*A + (W*B).T + Z*G

各行列を として初期化するとnp.matrix、適切な代数が自動的に実行されます。

import numpy as np
N = 5

A = np.asmatrix(np.arange(N)).T
B = np.asmatrix(np.arange(N)).T
G = np.asmatrix(np.arange(N)).T

X = np.asmatrix(np.arange(N*N).reshape(N,N))
W = np.asmatrix(np.arange(N*N).reshape(N,N))

Z = np.asmatrix(np.arange(N**3).reshape(N,N,N))

transpose1d 行列はデフォルトで行ベクトルであるため、1d 行列を使用したことに注意してください。真のベクトルは列ベクトルです。その後、ブロードキャストについて心配する必要はありません。

M = X*A + (W*B).T + Z*G
print M
[[  90  190  290  390  490]
 [ 390  490  590  690  790]
 [ 690  790  890  990 1090]
 [ 990 1090 1190 1290 1390]
 [1290 1390 1490 1590 1690]]
于 2013-03-11T16:26:30.417 に答える
1

簡単な例を見てみましょう。

定義すると:

import numpy as np
N = 5
A = np.arange(N)
X = np.arange(N*N).reshape(N,N)

B = np.arange(N)
W = np.arange(N*N).reshape(N,N)

G = np.arange(N)
Zij = np.arange(N)

次に、最初の合計は次のSum_v(Av * Xi_v)ように計算できますnp.dot

In [54]: X
Out[54]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

In [55]: A
Out[55]: array([0, 1, 2, 3, 4])

In [56]: np.dot(X, A)
Out[56]: array([ 30,  80, 130, 180, 230])

同様に、2 番目の合計は次のSum_v(Bv * Wj_v)ように計算できます。

In [58]: np.dot(W,B)
Out[58]: array([ 30,  80, 130, 180, 230])

ただし、最初の合計の結果がi-index に沿って変化するベクトルになるようにし、2 番目の合計の結果がj-index に沿って変化するベクトルになるようにします。それを numpy に配置するには、ブロードキャストを使用します。

In [59]: np.dot(X,A) + np.dot(W,B)[:,None]
Out[59]: 
array([[ 60, 110, 160, 210, 260],
       [110, 160, 210, 260, 310],
       [160, 210, 260, 310, 360],
       [210, 260, 310, 360, 410],
       [260, 310, 360, 410, 460]])

3 番目の合計は、2 つの 1 次元配列間の単純な内積です。

In [60]: np.dot(Zij, G)
Out[60]: 30

それで、すべてをまとめると、

In [61]: M = np.dot(X,A) + np.dot(W,B)[:,None] + np.dot(Zij, G)

In [62]: M
Out[62]: 
array([[ 90, 140, 190, 240, 290],
       [140, 190, 240, 290, 340],
       [190, 240, 290, 340, 390],
       [240, 290, 340, 390, 440],
       [290, 340, 390, 440, 490]])

の意味を誤解している可能性があることに注意してくださいZij。1次元配列だとおっしゃっていますが、おそらくそれぞれ i,jが1次元配列ということでしょうか。するとZ三次元になります。

具体的に言うと、 の最初の 2 つの軸がインデックスとインデックスをZ表し、の最後の軸が合計したい軸であるとします。ijZ

この場合、最後の項を次のようにする必要がありますnp.dot(Z, G)

In [13]: Z = np.arange(N**3).reshape(N,N,-1)

In [14]: np.dot(X,A) + np.dot(W,B)[:,None] + np.dot(Z, G)
Out[14]: 
array([[  90,  190,  290,  390,  490],
       [ 390,  490,  590,  690,  790],
       [ 690,  790,  890,  990, 1090],
       [ 990, 1090, 1190, 1290, 1390],
       [1290, 1390, 1490, 1590, 1690]])
于 2013-03-11T13:24:31.780 に答える