134 votes

Multiplication matricielle et matricielle en numpy

Numpy docs recommande d'utiliser un tableau plutôt qu'une matrice pour travailler avec des matrices. Cependant, contrairement à octave (que j'utilisais jusqu'à récemment), * n'effectue pas de multiplication de matrice, vous devez utiliser la fonction matrixmultipy (). Je pense que cela rend le code très illisible.

Quelqu'un partage-t-il mes points de vue et a-t-il trouvé une solution?

130voto

Joe Kington Points 68089

La raison principale pour éviter d'utiliser l' matrix classe est que a) il est intrinsèquement à 2 dimensions, et b) il y a une charge supplémentaire par rapport à un "normal" d'un tableau numpy. Si tout ce que vous faites est de l'algèbre linéaire, puis par tous les moyens, n'hésitez pas à utiliser la matrice de classe... Personnellement je trouve plus d'ennuis que cela vaut la peine, même si.

Pour les tableaux, utiliser dot au lieu de matrixmultiply.

E. g.

import numpy as np
x = np.arange(9).reshape((3,3))
y = np.arange(3)

print np.dot(x,y)

Ou dans des versions plus récentes de numpy, il suffit d'utiliser x.dot(y)

Personnellement, je trouve ça beaucoup plus lisible que l' * de l'opérateur ce qui implique la multiplication de matrice...

82voto

doug Points 29567

les points clés à connaître pour les opérations sur NumPy tableaux contre les opérations sur NumPy matrices sont:

  • NumPy est la matrice d'une sous-classe d'un tableau NumPy

  • Tableau NumPy opérations sont de l'élément de sage (une fois de radiodiffusion est prise en compte)

  • NumPy matrice des opérations de suivre les règles ordinaires de l'algèbre linéaire

quelques extraits de code:

>>> from numpy import linalg as LA

>>> import numpy as NP

>>> a1 = NP.matrix("4 3 5; 6 7 8; 1 3 13; 7 21 9")
>>> a1
matrix([[ 4,  3,  5],
        [ 6,  7,  8],
        [ 1,  3, 13],
        [ 7, 21,  9]])

>>> a2 = NP.matrix("7 8 15; 5 3 11; 7 4 9; 6 15 4")
>>> a2
matrix([[ 7,  8, 15],
        [ 5,  3, 11],
        [ 7,  4,  9],
        [ 6, 15,  4]])

>>> a1.shape
(4, 3)
>>> a2.shape
(4, 3)
>>> a2t = a2.T
>>> a2t.shape
(3, 4)

>>> a1 * a2t     # same as NP.dot(a1, a2t) 
matrix([[127,  84,  85,  89],
        [218, 139, 142, 173],
        [226, 157, 136, 103],
        [352, 197, 214, 393]])

mais cette opérations échoue, si ces deux NumPy matrices sont convertis à des tableaux:

>>> a1 = NP.array(a1)
>>> a2t = NP.array(a2t)

>>> a1 * a2t
Traceback (most recent call last):
   File "<pyshell#277>", line 1, in <module>
   a1 * a2t
   ValueError: operands could not be broadcast together with shapes (4,3) (3,4) 

cependant, l'utilisation de la NP.dot syntaxe fonctionne avec des tableaux; des opérations de travaux comme la matrice de la multiplication:

>> NP.dot(a1, a2t)
array([[127,  84,  85,  89],
       [218, 139, 142, 173],
       [226, 157, 136, 103],
       [352, 197, 214, 393]])

si vous avez besoin d'un NumPy matrice? c'est à dire, un tableau NumPy suffire pour l'algèbre linéaire (à condition de connaître la syntaxe correcte, c'est à dire, NP.dot)?

la règle semble être que si les arguments (tableaux) ont des formes (m x n) est-il compatible avec l'un d'algèbre linéaire de l'opération, alors vous êtes ok, sinon, NumPy lancers.

la seule exception que j'ai rencontré (il y en a probablement d'autres) est le calcul de la matrice inverse.

ci-dessous sont des extraits dans laquelle j'ai appelé une pure algèbre linéaire (en fait, à partir de Numpy de l'Algèbre Linéaire module) et transmis dans un tableau NumPy

déterminant d'une matrice:

>>> m = NP.random.randint(0, 10, 16).reshape(4, 4)
>>> m
array([[6, 2, 5, 2],
       [8, 5, 1, 6],
       [5, 9, 7, 5],
       [0, 5, 6, 7]])

>>> type(m)
<type 'numpy.ndarray'>

>>> md = LA.det(m)
>>> md
1772.9999999999995

les vecteurs propres/valeur propre paires:

>>> LA.eig(m)
(array([ 19.703+0.j   ,   0.097+4.198j,   0.097-4.198j,   5.103+0.j   ]), 
array([[-0.374+0.j   , -0.091+0.278j, -0.091-0.278j, -0.574+0.j   ],
       [-0.446+0.j   ,  0.671+0.j   ,  0.671+0.j   , -0.084+0.j   ],
       [-0.654+0.j   , -0.239-0.476j, -0.239+0.476j, -0.181+0.j   ],
       [-0.484+0.j   , -0.387+0.178j, -0.387-0.178j,  0.794+0.j   ]]))

matrice norme:

>>>> LA.norm(m)
22.0227

factorisation qr:

>>> LA.qr(a1)
(array([[ 0.5,  0.5,  0.5],
        [ 0.5,  0.5, -0.5],
        [ 0.5, -0.5,  0.5],
        [ 0.5, -0.5, -0.5]]), 
 array([[ 6.,  6.,  6.],
        [ 0.,  0.,  0.],
        [ 0.,  0.,  0.]]))

matrice de rang:

>>> m = NP.random.rand(40).reshape(8, 5)
>>> m
array([[ 0.545,  0.459,  0.601,  0.34 ,  0.778],
       [ 0.799,  0.047,  0.699,  0.907,  0.381],
       [ 0.004,  0.136,  0.819,  0.647,  0.892],
       [ 0.062,  0.389,  0.183,  0.289,  0.809],
       [ 0.539,  0.213,  0.805,  0.61 ,  0.677],
       [ 0.269,  0.071,  0.377,  0.25 ,  0.692],
       [ 0.274,  0.206,  0.655,  0.062,  0.229],
       [ 0.397,  0.115,  0.083,  0.19 ,  0.701]])
>>> LA.matrix_rank(m)
5

matrice condition:

>>> a1 = NP.random.randint(1, 10, 12).reshape(4, 3)
>>> LA.cond(a1)
5.7093446189400954

inversion nécessite un NumPy de la matrice :

>>> a1 = NP.matrix(a1)
>>> type(a1)
<class 'numpy.matrixlib.defmatrix.matrix'>

>>> a1.I
matrix([[ 0.028,  0.028,  0.028,  0.028],
        [ 0.028,  0.028,  0.028,  0.028],
        [ 0.028,  0.028,  0.028,  0.028]])
>>> a1 = NP.array(a1)
>>> a1.I

Traceback (most recent call last):
   File "<pyshell#230>", line 1, in <module>
   a1.I
   AttributeError: 'numpy.ndarray' object has no attribute 'I'

mais l' Moore-Penrose pseudo-inverse semble fonctionne très bien

>>> LA.pinv(m)
matrix([[ 0.314,  0.407, -1.008, -0.553,  0.131,  0.373,  0.217,  0.785],
        [ 1.393,  0.084, -0.605,  1.777, -0.054, -1.658,  0.069, -1.203],
        [-0.042, -0.355,  0.494, -0.729,  0.292,  0.252,  1.079, -0.432],
        [-0.18 ,  1.068,  0.396,  0.895, -0.003, -0.896, -1.115, -0.666],
        [-0.224, -0.479,  0.303, -0.079, -0.066,  0.872, -0.175,  0.901]])

>>> m = NP.array(m)

>>> LA.pinv(m)
array([[ 0.314,  0.407, -1.008, -0.553,  0.131,  0.373,  0.217,  0.785],
       [ 1.393,  0.084, -0.605,  1.777, -0.054, -1.658,  0.069, -1.203],
       [-0.042, -0.355,  0.494, -0.729,  0.292,  0.252,  1.079, -0.432],
       [-0.18 ,  1.068,  0.396,  0.895, -0.003, -0.896, -1.115, -0.666],
       [-0.224, -0.479,  0.303, -0.079, -0.066,  0.872, -0.175,  0.901]])

21voto

Petr Viktorin Points 13687

3.5 de Python est enfin obtenir un opérateur de multiplication de matrice. La syntaxe sera `` .

15voto

ASDF Points 123

Il existe une situation où l'opérateur de points donnera des réponses différentes lorsqu'il s'agit de tableaux ou de matrices. Par exemple, supposons ce qui suit:

 >>> a=numpy.array([1, 2, 3])
>>> b=numpy.array([1, 2, 3])
 

Permet de les convertir en matrices:

 >>> am=numpy.mat(a)
>>> bm=numpy.mat(b)
 

Maintenant, nous pouvons voir une sortie différente pour les deux cas:

 >>> print numpy.dot(a.T, b)
14
>>> print am.T*bm
[[1.  2.  3.]
 [2.  4.  6.]
 [3.  6.  9.]]
 

13voto

Luka Rahne Points 5479

Ce devrait être pareil, regardez ici http://www.scipy.org/NumPy_for_Matlab_Users (pensez à MATLAB en tant que clone d'Octave)

Avez-vous vraiment un type de matrice ou juste une liste de listes de python?

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