Numpy einsum menghitung hasil kali luar sepanjang sumbu
Saya memiliki dua array numpy yang berisi matriks yang kompatibel dan ingin menghitung produk luar yang bijak dari elemen menggunakan numpy.einsum . Bentuk dari array tersebut adalah:
A1 = (i,j,k)
A2 = (i,k,j)
Oleh karena itu array mengandung i
matriks bentuk (k,j)
dan (j,k)
masing - masing.
Jadi diberikan A1
akan berisi matriks A,B,C
dan A2
akan berisi matriks D,E,F
, hasilnya adalah:
A3 = (A(x)D,B(x)E,C(x)F)
Dengan (x)
menjadi operator produk luar.
Ini akan menghasilkan pemahaman saya berdasarkan jawaban ini sebuah array A3
dari bentuk berikut:
A3 = (i,j*k,j*k)
Sejauh ini saya sudah mencoba:
np.einsum("ijk, ilm -> ijklm", A1, A2)
Namun bentuk yang dihasilkan tidak pas.
Sebagai pemeriksaan kewarasan saya menguji ini:
A = np.asarray(([1,2],[3,4]))
B = np.asarray(([5,6],[7,8]))
AB_outer = np.outer(A,B)
A_vec = np.asarray((A,A))
B_vec = np.asarray((B,B))
# this line is not correct
AB_vec = np.einsum("ijk, ilm -> ijklm", A_vec,B_vec)
np.testing.assert_array_equal(AB_outer, AB_vec[0])
Ini saat ini melempar kesalahan pernyataan karena notasi einsum saya tidak benar. Saya juga terbuka untuk setiap saran yang dapat mengatasi ini dan lebih cepat atau sama cepatnya dengan nimfa einsum.
Jawaban
Kami dapat memperpanjang masa redup dan broadcastingmelakukan pekerjaan untuk kami -
(A1[:,:,None,:,None]*A2[:,None,:,None,:]).swapaxes(2,3)
Contoh run -
In [46]: A1 = np.random.rand(3,4,4)
...: A2 = np.random.rand(3,4,4)
In [47]: out = (A1[:,:,None,:,None]*A2[:,None,:,None,:]).swapaxes(2,3)
In [48]: np.allclose(np.multiply.outer(A1[0],A2[0]), out[0])
Out[48]: True
In [49]: np.allclose(np.multiply.outer(A1[1],A2[1]), out[1])
Out[49]: True
In [50]: np.allclose(np.multiply.outer(A1[2],A2[2]), out[2])
Out[50]: True
Setara dengan np.einsumakan -
np.einsum('ijk,ilm->ijklm',A1,A2)
Anda dapat menghitung hasil dengan berjalan:
result = np.einsum('ijk,ikl->ijl', A1, A2)
Saya memeriksa kode di atas pada data uji berikut:
A = np.arange(1, 13).reshape(3, -1)
B = np.arange(2, 14).reshape(3, -1)
C = np.arange(3, 15).reshape(3, -1)
D = np.arange(1, 13).reshape(4, -1)
E = np.arange(2, 14).reshape(4, -1)
F = np.arange(3, 15).reshape(4, -1)
A1 = np.array([A, B, C])
A2 = np.array([D, E, F])
Hasilnya adalah:
array([[[ 70, 80, 90],
[158, 184, 210],
[246, 288, 330]],
[[106, 120, 134],
[210, 240, 270],
[314, 360, 406]],
[[150, 168, 186],
[270, 304, 338],
[390, 440, 490]]])
Sekarang hitung 3 "hasil parsial":
res_1 = A @ D
res_2 = B @ E
res_3 = C @ F
dan periksa apakah bagian tersebut sama dengan bagian yang berurutan dari hasil.