web-dev-qa-db-fra.com

Multiplication de matrices numpy

Lorsque je multiplie deux tableaux numpy de tailles (n x n) * (n x 1), je reçois une matrice de taille (n x n). Suivant les règles normales de multiplication de matrice, un vecteur (n x 1) est attendu, mais je ne trouve aucune information sur la manière dont cela est effectué dans le module Numpy de Python.

Le fait est que je ne veux pas l'implémenter manuellement pour préserver la vitesse du programme.

Exemple de code est montré ci-dessous:

a = np.array([[ 5, 1 ,3], [ 1, 1 ,1], [ 1, 2 ,1]])
b = np.array([1, 2, 3])

print a*b
   >>
   [[5 2 9]
   [1 2 3]
   [1 4 3]]

Ce que je veux c'est:

print a*b
   >>
   [16 6 8]
153
user3272574

Solution la plus simple

Utilisez _numpy.dot_ ou a.dot(b). Voir la documentation ici .

_>>> a = np.array([[ 5, 1 ,3], 
                  [ 1, 1 ,1], 
                  [ 1, 2 ,1]])
>>> b = np.array([1, 2, 3])
>>> print a.dot(b)
array([16, 6, 8])
_

Cela est dû au fait que les tableaux numpy ne sont pas des matrices et que les opérations standard _*, +, -, /_ fonctionnent par élément sur les tableaux. Au lieu de cela, vous pouvez essayer d'utiliser numpy.matrix , et _*_ sera traité comme une multiplication de matrice.


Autres solutions

Sachez également qu'il existe d'autres options:

  • Comme indiqué ci-dessous, si vous utilisez python3.5 +, l'opérateur _@_ fonctionne comme prévu:

    _>>> print(a @ b)
    array([16, 6, 8])
    _
  • Si vous voulez exagérer, vous pouvez utiliser numpy.einsum . La documentation vous donnera une idée de son fonctionnement, mais honnêtement, je n’ai pas bien compris comment l’utiliser avant de lire cette réponse et de me débrouiller seul.

    _>>> np.einsum('ji,i->j', a, b)
    array([16, 6, 8])
    _
  • À partir de la mi-2016 (numpy 1.10.1), vous pouvez essayer le test numpy.matmul , qui fonctionne comme _numpy.dot_ avec deux exceptions principales: pas de multiplication scalaire mais cela fonctionne avec des piles de matrices.

    _>>> np.matmul(a, b)
    array([16, 6, 8])
    _
  • numpy.inner fonctionne de la même manière que _numpy.dot_ pour la multiplication matrice-vecteur, mais se comporte différemment pour la matrice -matrix et multiplication tenseur (voir Wikipedia concernant les différences entre le produit intérieur et le produit scalaire en général ou voir cette SO réponse en ce qui concerne les implémentations de numpy).

    _>>> np.inner(a, b)
    array([16, 6, 8])
    
    # Beware using for matrix-matrix multiplication though!
    >>> b = a.T
    >>> np.dot(a, b)
    array([[35,  9, 10],
           [ 9,  3,  4],
           [10,  4,  6]])
    >>> np.inner(a, b) 
    array([[29, 12, 19],
           [ 7,  4,  5],
           [ 8,  5,  6]])
    _

Options plus rares pour les cas Edge

  • Si vous avez des tenseurs (des tableaux de dimension supérieure ou égale à un), vous pouvez utiliser numpy.tensordot avec l'argument optionnel _axes=1_:

    _>>> np.tensordot(a, b, axes=1)
    array([16,  6,  8])
    _
  • N'utilisez pas numpy.vdot si vous avez une matrice de nombres complexes, car celle-ci sera aplatie. un tableau 1D, il essaiera ensuite de trouver le produit de points conjugué complexe entre votre matrice aplatie et votre vecteur (ce qui échouera en raison d’un décalage de taille _n*m_ vs n).

243
wflynny