2 votes

la matrice multiplie chaque paire de tableaux 2-D le long de la première dimension avec einsum

J'ai deux tableaux 3D de la même taille. a y b

np.random.seed([3,14159])
a = np.random.randint(10, size=(4, 3, 2))
b = np.random.randint(10, size=(4, 3, 2))

print(a)

[[[4 8]
  [1 1]
  [9 2]]

 [[8 1]
  [4 2]
  [8 2]]

 [[8 4]
  [9 4]
  [3 4]]

 [[1 5]
  [1 2]
  [6 2]]]

print(b)

[[[7 7]
  [1 1]
  [7 8]]

 [[7 4]
  [8 0]
  [0 9]]

 [[3 8]
  [7 7]
  [2 6]]

 [[3 1]
  [9 3]
  [0 5]]]

Je veux prendre le premier tableau d'un

a[0]

[[4 8]
 [1 1]
 [9 2]]

Et le premier de b

b[0]

[[7 7]
 [1 1]
 [7 8]]

Et renvoyer ceci

a[0].T.dot(b[0])

[[ 92 101]
 [ 71  73]]

Mais je veux le faire sur toute la première dimension. Je pensais que je pourrais utiliser np.einsum

np.einsum('abc,ade->ace', a, b)

[[[210 224]
  [165 176]]

 [[300 260]
  [ 75  65]]

 [[240 420]
  [144 252]]

 [[ 96  72]
  [108  81]]]

C'est la forme correcte, mais pas les valeurs.

Je m'attends à recevoir ça :

np.array([x.T.dot(y).tolist() for x, y in zip(a, b)])

[[[ 92 101]
  [ 71  73]]

 [[ 88 104]
  [ 23  22]]

 [[ 93 145]
  [ 48  84]]

 [[ 12  34]
  [ 33  21]]]

2voto

unutbu Points 222216

La multiplication matricielle revient à une somme de produits où la somme est prise sur l'axe médian, donc l'indice b doit être le même pour les deux tableaux (c'est-à-dire qu'il faut modifier ade à abe ):

In [40]: np.einsum('abc,abe->ace', a, b)
Out[40]: 
array([[[ 92, 101],
        [ 71,  73]],

       [[ 88, 104],
        [ 23,  22]],

       [[ 93, 145],
        [ 48,  84]],

       [[ 12,  34],
        [ 33,  21]]])

Lorsque les tableaux d'entrée ont des indices qui manquent dans le tableau de sortie, ils sont additionnés indépendamment. C'est-à-dire,

np.einsum('abc,ade->ace', a, b)

est équivalent à

In [44]: np.einsum('abc,ade->acebd', a, b).sum(axis=-1).sum(axis=-1)
Out[44]: 
array([[[210, 224],
        [165, 176]],

       [[300, 260],
        [ 75,  65]],

       [[240, 420],
        [144, 252]],

       [[ 96,  72],
        [108,  81]]])

2voto

Divakar Points 20144

En voici un avec np.matmul car nous devons repousser le deuxième axe de a jusqu'à la fin, pour qu'il obtienne sum-reduced contre le deuxième axe de b tout en gardant leurs premiers axes alignés -

np.matmul(a.swapaxes(1,2),b) 

Schématiquement :

Au départ :

a   :  M x N X R1
b   :  M x N X R2

Avec des axes permutés pour un :

a   :  M x R1 X [N]
b   :  M x [N] X R2

Les axes entre parenthèses donnent sum-reduced ce qui nous laisse avec :

out :   M x R1 X R2

Sur Python 3.x, matmul est pris en charge par @ operator -

a.swapaxes(1,2) @ b

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X