¿Cuáles son las diferencias entre matrices numpy y matrices? ¿Cuál debo usar?

346

¿Cuales son las ventajas y desventajas de cada uno?

Por lo que he visto, cualquiera de los dos puede funcionar como un reemplazo para el otro si es necesario, así que ¿debería molestarme en usar ambos o debería limitarme a uno solo?

¿El estilo del programa influirá en mi elección? Estoy haciendo un aprendizaje automático usando numpy, por lo que hay muchas matrices, pero también muchos vectores (matrices).

levesco
fuente
3
No tengo suficiente información para justificar una respuesta, pero por lo que puedo decir, la principal diferencia es la implementación de la multiplicación. Una matriz realiza la multiplicación matriz / tensor, mientras que una matriz realizará la multiplicación por elementos.
Mike Axiak
55
Python 3.5 agregó el operador infix @ para la multiplicación de matrices (PEP 465), y NumPy 1.10 agregó soporte para ello. Entonces, si está utilizando Python 3.5+ y NumPy 1.10+, puede escribir en A @ Blugar de A.dot(B), where Ay Bson 2D ndarrays. Esto elimina la ventaja principal de usar en matrixlugar de simples ndarray, en mi humilde opinión.
MiniQuark

Respuestas:

396

Las matrices Numpy son estrictamente bidimensionales, mientras que las matrices numpy (ndarrays) son N-dimensionales. Los objetos de matriz son una subclase de ndarray, por lo que heredan todos los atributos y métodos de ndarrays.

La principal ventaja de las matrices numpy es que proporcionan una notación conveniente para la multiplicación de matrices: si ayb son matrices, entonces a*bes su producto matricial.

import numpy as np

a = np.mat('4 3; 2 1')
b = np.mat('1 2; 3 4')
print(a)
# [[4 3]
#  [2 1]]
print(b)
# [[1 2]
#  [3 4]]
print(a*b)
# [[13 20]
#  [ 5  8]]

Por otro lado, a partir de Python 3.5, NumPy admite la multiplicación de matriz infija usando el @operador, por lo que puede lograr la misma conveniencia de la multiplicación de matriz con ndarrays en Python> = 3.5.

import numpy as np

a = np.array([[4, 3], [2, 1]])
b = np.array([[1, 2], [3, 4]])
print(a@b)
# [[13 20]
#  [ 5  8]]

Tanto los objetos de matriz como los ndarrays tienen .Tque devolver la transposición, pero los objetos de matriz también tienen .Hpara la transposición conjugada y .Ipara la inversa.

Por el contrario, los arreglos numpy cumplen de manera consistente con la regla de que las operaciones se aplican por elementos (excepto para el nuevo @operador). Por lo tanto, si ay bson matrices numpy, entonces a*bla matriz se forma multiplicando los componentes por elementos:

c = np.array([[4, 3], [2, 1]])
d = np.array([[1, 2], [3, 4]])
print(c*d)
# [[4 6]
#  [6 4]]

Para obtener el resultado de la multiplicación de matrices, use np.dot(o @en Python> = 3.5, como se muestra arriba):

print(np.dot(c,d))
# [[13 20]
#  [ 5  8]]

El **operador también se comporta de manera diferente:

print(a**2)
# [[22 15]
#  [10  7]]
print(c**2)
# [[16  9]
#  [ 4  1]]

Como aes una matriz, a**2devuelve el producto de la matriz a*a. Como ces un ndarray, c**2devuelve un ndarray con cada componente al cuadrado en cuanto a elementos.

Existen otras diferencias técnicas entre los objetos de matriz y los ndarrays (que tienen que ver con la np.ravelselección de elementos y el comportamiento de la secuencia).

La principal ventaja de las matrices numpy es que son más generales que las matrices bidimensionales . ¿Qué sucede cuando quieres una matriz tridimensional? Luego debe usar un ndarray, no un objeto de matriz. Por lo tanto, aprender a usar objetos matriciales es más trabajo: hay que aprender las operaciones de objetos matriciales y las operaciones ndarray.

Escribir un programa que mezcle matrices y matrices te dificulta la vida porque tienes que hacer un seguimiento de qué tipo de objeto son tus variables, para que la multiplicación no devuelva algo que no esperas.

Por el contrario, si se limita únicamente a los ndarrays, puede hacer todo lo que pueden hacer los objetos matriciales, y más, excepto con funciones / notación ligeramente diferentes.

Si está dispuesto a renunciar al atractivo visual de la notación de productos de matriz NumPy (que se puede lograr de manera casi tan elegante con ndarrays en Python> = 3.5), entonces creo que los arreglos NumPy son definitivamente el camino a seguir.

PD. Por supuesto, usted realmente no tiene que elegir uno a expensas del otro, desde np.asmatrixy np.asarraypermitirá convertir una a la otra (siempre y cuando la matriz es de 2 dimensiones).


Hay una sinopsis de las diferencias entre NumPy arraysvs NumPy matrixes aquí .

unutbu
fuente
77
Para aquellos que se preguntan, mat**nporque una matriz se puede aplicar de manera poco elegante a una matriz conreduce(np.dot, [arr]*n)
askewchan
66
O simplementenp.linalg.matrix_power(mat, n)
Eric
Me pregunto si las matrices serían más rápidas ... pensarías que tienen que realizar menos controles que ndarray.
PascalVKooten
1
En realidad, las pruebas de timeit muestran operaciones ndarray como np.dot(array2, array2)son más rápidas que matrix1*matrix2. Esto tiene sentido porque matrixes una subclase de ndarray que anula métodos especiales como __mul__. matrix.__mul__llamadasnp.dot . Así que hay reutilización de código aquí. En lugar de realizar menos comprobaciones, el uso matrix*matrixrequiere una llamada de función adicional. Entonces, la ventaja de usar matrixes puramente sintáctica, no un mejor rendimiento.
unutbu
4 * 1 + 3 * 3 te da 13 cuando hiciste np.dot (c, d) esto no es realmente un producto cruzado en matemáticas
PirateApp
92

Scipy.org recomienda que use matrices:

* 'matriz' o 'matriz'? ¿Cuál debería usar? - Respuesta corta

Usa matrices.

  • Son el tipo estándar de vector / matriz / tensor de numpy. Muchas funciones numpy devuelven matrices, no matrices.

  • Existe una clara distinción entre operaciones basadas en elementos y operaciones de álgebra lineal.

  • Puede tener vectores estándar o vectores de fila / columna si lo desea.

La única desventaja de usar el tipo de matriz es que tendrá que usar en dotlugar de *multiplicar (reducir) dos tensores (producto escalar, multiplicación de vectores de matriz, etc.).

atomh33ls
fuente
11
A pesar de que la respuesta aceptada proporciona más información, la respuesta real es quedarse ndarray. El argumento principal para usar matrixsería si su código es pesado en álgebra lineal y se vería menos claro con todas las llamadas a la dotfunción. Pero este argumento desaparecerá en el futuro, ahora que el operador @ es aceptado para su uso con la multiplicación de matrices, ver PEP 465 . Esto necesitará Python 3.5 y la última versión de Numpy. La clase de matriz podría quedar obsoleta en el futuro lejano, por lo que es mejor usar ndarray para el nuevo código ...
Bas Swinckels
66
Esa página gentilmente se olvida de las scipy.sparsematrices. Si usa matrices densas y dispersas en su código, es mucho más fácil seguirlas matrix.
David Nemeskey
3
En mi opinión, la principal desventaja de las matrices es que el corte de columnas devuelve matrices planas que pueden ser confusas y matemáticamente no son realmente sólidas. Esto también lleva a la desventaja importante de que las matrices numpy no se pueden tratar de la misma manera que las matrices scipy.sparse, mientras que las matrices numpy básicamente se pueden intercambiar libremente con matrices dispersas. Es absurdo en este contexto que scipy recomiende usar matrices y luego no proporcione matrices dispersas compatibles.
Radio controlado el
29

Solo para agregar un caso a la lista de unutbu.

Una de las mayores diferencias prácticas para mí de ndarrays numpy en comparación con matrices numpy o lenguajes matriciales como matlab, es que la dimensión no se conserva en operaciones de reducción. Las matrices son siempre 2d, mientras que la media de una matriz, por ejemplo, tiene una dimensión menos.

Por ejemplo, degradar filas de una matriz o matriz:

con matriz

>>> m = np.mat([[1,2],[2,3]])
>>> m
matrix([[1, 2],
        [2, 3]])
>>> mm = m.mean(1)
>>> mm
matrix([[ 1.5],
        [ 2.5]])
>>> mm.shape
(2, 1)
>>> m - mm
matrix([[-0.5,  0.5],
        [-0.5,  0.5]])

con matriz

>>> a = np.array([[1,2],[2,3]])
>>> a
array([[1, 2],
       [2, 3]])
>>> am = a.mean(1)
>>> am.shape
(2,)
>>> am
array([ 1.5,  2.5])
>>> a - am #wrong
array([[-0.5, -0.5],
       [ 0.5,  0.5]])
>>> a - am[:, np.newaxis]  #right
array([[-0.5,  0.5],
       [-0.5,  0.5]])

También creo que mezclar matrices y matrices da lugar a muchas horas de depuración "felices". Sin embargo, las matrices scipy.sparse son siempre matrices en términos de operadores como la multiplicación.

Josef
fuente