La numpy docs recomienda utilizar la matriz de cambio de la matriz para trabajar con matrices. Sin embargo, a diferencia de la octava (que estaba usando hasta hace poco), * no realizar la multiplicación de la matriz, es necesario utilizar la función matrixmultipy(). Yo siento que esto hace que el código sea muy ilegible.

¿Alguien comparte mis puntos de vista, y ha encontrado una solución?

  • Usted está pidiendo opiniones y no una pregunta. Hay algo más específico que nos podría ayudar o tal vez de guía, lo que es más legible?
  • En realidad, los médicos recomiendan el uso de la matriz si usted álgebra lineal y no wan’t para el uso de multiplicar() así que ¿cuál es el problema?
  • No he ido a través de los documentos en detalle. Sólo por curiosidad, ¿qué ventajas de las matrices de oferta sobre la matriz de la clase? He encontrado que las matrices no diferencian entre filas y columnas. Es a causa de que las matrices se supone que para ser considerado como tensores en lugar de matrices? Como Joe señaló, el hecho de que la matriz de la clase es de 2-dim es bastante limitante. ¿Cuál es la idea detrás de este tipo de diseño, como en, ¿por qué no tener una sola matriz de clase como matlab/octave?
  • Supongo que el principal problema es que python no tiene .* vs ‘*’ sintaxis para el elemento sabio vs multiplicación de la matriz. Si tuviera que entonces todo sería más sencillo, aunque me sorprende que elegir * a significar el elemento más sabio, y no la multiplicación de la matriz.
InformationsquelleAutor elexhobby | 2010-10-08

8 Comentarios

  1. 126

    La principal razón para evitar el uso de la matrix clase es que a) es inherentemente 2-dimensional, y b) hay una sobrecarga adicional en comparación con una «normal» numpy matriz. Si todo lo que estamos haciendo es álgebra lineal, entonces por todos los medios, siéntase libre de usar la clase matrix… Personalmente creo que es más problemas de lo que vale, aunque.

    Para las matrices (antes de Python 3.5), el uso de punto en lugar de matrixmultiply.

    E. g.

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

    O en las versiones más recientes de numpy, simplemente uso x.dot(y)

    Personalmente, me resulta mucho más legible que la * operador, lo que implica la multiplicación de la matriz…

    Para las matrices en Python 3.5, uso x @ y.

    • Su ilegibles cuando usted tiene una pila de fichas de multiplicaciones, por ejemplo x’A’*Ax.
    • no es que no se puede leer, yo.m.o. A cada uno lo suyo, aunque. Si usted está principalmente haciendo la multiplicación de la matriz, entonces por todos los medios, el uso de numpy.matrix!
    • Por cierto, ¿por qué es la multiplicación de la matriz se llama «punto»? ¿En qué sentido es un punto del producto?
    • La multiplicación de la matriz se refiere a veces como un «producto escalar» en los libros de texto (en los libros, es el punto que producto que usted está pensando es llamado un «producto escalar» o «escalar producto escalar»). El escalar producto escalar es simplemente la multiplicación de la matriz de dos vectores, después de todo, de modo que el «punto» para referirse a la multiplicación de la matriz, en general, no es mucho de un estiramiento. Que en particular la notación parece (?) más común en la ingeniería y ciencia de los textos que en matemáticas, al menos en mi experiencia. Su prevalencia en numpy es principalmente porque numpy.matrixmultiply es difícil de escribir.
    • También, matrixmultiply fue depreciado hace muchos años, y ha sido eliminado en cualquiera de los últimos-ish (>v1.3, tal vez?) la versión de numpy.
    • Es el escalar producto escalar en realidad sólo la multiplicación de la matriz de dos vectores? Si el operador * es la multiplicación de la matriz, a continuación, u.T * v sería el escalar producto escalar, pero u * v sería indefinido (ya que las dimensiones no coinciden). Si la multiplicación de la matriz se define como una suma sobre el último eje de la izquierda de la matriz con el segundo al último eje de la derecha de la matriz, entonces supongo que la multiplicación de la matriz de 1-D arrays de numpy podría fallar debido a que el derecho de la matriz no tiene un segundo a último eje. De todos modos, es por eso que estoy confundido.
    • es los casos especiales que se comportan como inner por 1d vectores. El producto interior de dos 1D vectores es estrictamente idéntica a la de escalar producto escalar. (Por cierto, u.T y u son idénticos si u es unidimensional. «Vectores fila» y «columna de vectores» son en 2D, y no son vectores, estrictamente hablando. En numpy, los vectores son vectores, y no tienen una 2ª dimensión, así que tienes que remodelar en 2D a tener un vector fila o vector columna.)
    • Agradezco que numpy.dot se comporta como un producto interior de una dimensión de los vectores, pero este especial de la carcasa hace que la función parecen auto-incompatibles. Tal vez yo sería menos confuso si fueron más comunes para que los libros se refieren a «punto» para la multiplicación de la matriz como la que usted describe. De todos modos, entiendo lo suficiente como para usarlo, pero no me gusta la obligación siento ensuciar el código con comentarios explicando que numpy.dot realiza la multiplicación de la matriz.
    • el punto es que el dot generaliza arbitraria de la dimensionalidad sin ambigüedad. Es esto lo que hace numpy.dot equivalente a la multiplicación de la matriz. Si realmente no te gusta la notación, el uso de la matrix clase.
    • Espero no te importa he actualizado tu respuesta para Python 3.5
    • Para mí el dot también parece antinatural nombre, y era confuso al principio.
    • Un punto importante a destacar aquí es * es el elemento sabio multiplicación de puntos, es la verdadera multiplicación de la matriz. Por favor, consulte stackoverflow.com/a/18255635/1780570
    • Es cierto que la multiplicación de matrices y el producto escalar entre dos vectores se realiza de manera muy similar; sin embargo, el producto escalar entre dos vectores de viaje, mientras que el de la multiplicación de matrices no.
    • Supongo que el principal problema es que python no tiene .* vs ‘*’ sintaxis para el elemento sabio vs multiplicación de la matriz. Si tuviera que entonces todo sería más sencillo, aunque me sorprende que elegir * a significar el elemento más sabio, y no la multiplicación de la matriz.
    • el uso de dot para la multiplicación de la matriz es TERRIBLE la notación ya que el producto escalar de vectores y la matriz de múltiples son muy diferentes operaciones. Por ejemplo, el producto escalar de dos vectores es conmutativa, es decir, a.dot(b) == b.dot(a) (o al menos debería ser de acuerdo con la definición del producto escalar). En la multiplicación de la matriz np.matmul(a,b) != np.matmul(b,a)

  2. 81

    la clave de cosas que hay que saber para las operaciones en NumPy matrices frente a las operaciones en NumPy matrices son:

    • NumPy matriz es un subclase de NumPy matriz

    • NumPy matriz las operaciones de elemento sabio (una vez que la radiodifusión es justificado)

    • NumPy matriz operaciones de seguir las reglas ordinarias de álgebra lineal

    algunos fragmentos de código para ilustrar:

    >>> 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]])

    pero esta operación produce un error si estos dos NumPy matrices se convierten en matrices:

    >>> 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) 

    aunque el uso de la NP.punto sintaxis funciona con matrices; esta operación funciona como la multiplicación de la matriz:

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

    así que, ¿alguna vez necesitas un NumPy de la matriz? es decir, será una Colección de matriz suficiente para álgebra lineal cálculo (siempre y cuando se conozca la sintaxis correcta, es decir, NP.dot)?

    la regla parece ser que si los argumentos (arrays) tienen formas (m x n) compatible con un determinado álgebra lineal, entonces usted está bien, de lo contrario, NumPy lanza.

    la única excepción que he encontrado (hay otros) es el cálculo de la matriz inversa.

    a continuación son fragmentos en los que he llamado una pura álgebra lineal operación (de hecho, a partir de Numpy del Álgebra Lineal módulo) y se pasa en un NumPy matriz

    determinante de una matriz:

    >>> 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

    vectores propios/autovalor pares:

    >>> 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   ]]))

    matriz norma:

    >>>> LA.norm(m)
    22.0227

    factorización 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.]]))

    matriz rango:

    >>> 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

    matriz condición:

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

    inversión requiere de una Colección que matriz aunque:

    >>> 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'

    pero la Moore-Penrose pseudoinverse parece que funciona 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]])
    • mInv = NP.linalg.inv(m) calcula la inversa de una matriz
    • Un punto importante a destacar aquí es * es el elemento sabio multiplicación de puntos, es la verdadera multiplicación de la matriz. Por favor, consulte stackoverflow.com/a/18255635/1780570
  3. 15

    Hay una situación en la que el operador va a dar diferentes respuestas a la hora de tratar con matrices como con el trato con las matrices. Por ejemplo, supongamos la siguiente:

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

    Permite convertirlos en matrices:

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

    Ahora, podemos ver una salida diferente para los dos casos:

    >>> print numpy.dot(a.T, b)
    14
    >>> print am.T*bm
    [[1.  2.  3.]
    [2.  4.  6.]
    [3.  6.  9.]]
    • Para ser más específicos, * es el elemento sabio multiplicación de puntos, es la verdadera multiplicación de la matriz. Por favor, consulte stackoverflow.com/a/18255635/1780570
    • Eso es porque como numpy matriz, una.T == a, la transposición de no hacer nada.
    • Si usted escribe a = np.matriz([[1],[2],[3]]), a continuación, numpy.dot(a,b) debe dar a usted mismo. La diferencia entre matix y la matriz no está en el punto, pero en la transposición.
    • O, en realidad, si se escribe a = numpy.array([[1,2,3]]), a continuación, una.T realmente va a incorporar y todo funcionará igual que en las matrices.
  4. 8

    De referencia de http://docs.scipy.org/doc/scipy/reference/tutorial/linalg.html

    …, el uso de la numpy.matriz de clase es desanimado, ya que no aporta nada que no se puede lograr con 2D numpy.ndarray objetos, y puede conducir a un confusión de la clase que está siendo utilizado. Por ejemplo,

    >>> import numpy as np
    >>> from scipy import linalg
    >>> A = np.array([[1,2],[3,4]])
    >>> A
    array([[1, 2],
    [3, 4]])
    >>> linalg.inv(A)
    array([[-2. ,  1. ],
    [ 1.5, -0.5]])
    >>> b = np.array([[5,6]]) #2D array
    >>> b
    array([[5, 6]])
    >>> b.T
    array([[5],
    [6]])
    >>> A*b #not matrix multiplication!
    array([[ 5, 12],
    [15, 24]])
    >>> A.dot(b.T) #matrix multiplication
    array([[17],
    [39]])
    >>> b = np.array([5,6]) #1D array
    >>> b
    array([5, 6])
    >>> b.T  #not matrix transpose!
    array([5, 6])
    >>> A.dot(b)  #does not matter for multiplication
    array([17, 39])

    scipy.linalg operaciones pueden ser aplicadas por igual a numpy.matriz de o 2D numpy.ndarray objetos.

  5. 7

    Este truco podría ser lo que usted está buscando. Es una especie de simple sobrecarga de operadores.

    Usted puede, a continuación, utilizar algo parecido a la propuesta de Infix clase como esta:

    a = np.random.rand(3,4)
    b = np.random.rand(4,3)
    x = Infix(lambda x,y: np.dot(x,y))
    c = a |x| b
  6. 5

    Pertinente la cita de PEP 465 – UN operador infijo para la multiplicación de la matriz , como se ha mencionado por @petr-viktorin, aclara el problema de la OP fue conseguir en:

    […] numpy dispone de dos tipos diferentes con diferentes __mul__ métodos. Para numpy.ndarray objetos, * realiza elementwise la multiplicación, y la multiplicación de la matriz debe utilizar una llamada a una función (numpy.dot). Para numpy.matrix objetos, * realiza la multiplicación de la matriz, y elementwise multiplicación requiere la sintaxis de la función. Escribir código con numpy.ndarray funciona bien. Escribir código con numpy.matrix también funciona bien. Pero los problemas comienza tan pronto como tratamos de integrar estas dos piezas de código. Código que espera un ndarray y consigue un matrix, o viceversa, puede bloquearse o devolver resultados incorrectos

    La introducción de la @ infix operador debe ayudar a unificar y simplificar python código de matriz.

  7. 1

    Función matmul (desde numpy 1.10.1) funciona bien para ambos tipos y devolver el resultado como una colección de la matriz de la clase:

    import numpy as np
    A = np.mat('1 2 3; 4 5 6; 7 8 9; 10 11 12')
    B = np.array(np.mat('1 1 1 1; 1 1 1 1; 1 1 1 1'))
    print (A, type(A))
    print (B, type(B))
    C = np.matmul(A, B)
    print (C, type(C))

    De salida:

    (matrix([[ 1,  2,  3],
    [ 4,  5,  6],
    [ 7,  8,  9],
    [10, 11, 12]]), <class 'numpy.matrixlib.defmatrix.matrix'>)
    (array([[1, 1, 1, 1],
    [1, 1, 1, 1],
    [1, 1, 1, 1]]), <type 'numpy.ndarray'>)
    (matrix([[ 6,  6,  6,  6],
    [15, 15, 15, 15],
    [24, 24, 24, 24],
    [33, 33, 33, 33]]), <class 'numpy.matrixlib.defmatrix.matrix'>)

    Desde python 3.5 como mencionó la también puede utilizar una nueva matriz del operador de multiplicación @ como

    C = A @ B

    y obtener el mismo resultado que el anterior.

Dejar respuesta

Please enter your comment!
Please enter your name here