3 formas de multiplicar matrices en Python

En este tutorial, aprenderá a multiplicar dos matrices en Python.

Comenzará aprendiendo la condición para la multiplicación de matrices válida y escribirá una función de Python personalizada para multiplicar matrices. A continuación, verá cómo puede lograr el mismo resultado utilizando comprensiones de listas anidadas.

Finalmente, procederá a usar NumPy y sus funciones integradas para realizar la multiplicación de matrices de manera más eficiente.

Cómo verificar si la multiplicación de matrices es válida

Antes de escribir el código de Python para la multiplicación de matrices, revisemos los conceptos básicos de la multiplicación de matrices.

La multiplicación de matrices entre dos matrices A y B es válida solo si el número de columnas en la matriz A es igual al número de filas en la matriz B.

Es probable que te hayas encontrado con esta condición para la multiplicación de matrices antes. Sin embargo, ¿alguna vez te has preguntado por qué es así?

Bueno, es por la forma en que funciona la multiplicación de matrices. Hecha un vistazo a la imagen de abajo.

En nuestro ejemplo genérico, la matriz A tiene m filas y n columnas. Y la matriz B tiene n filas y p columnas.

¿Cuál es la forma de la matriz del producto?

El elemento en el índice (i, j) en la matriz resultante C es el producto escalar de la fila i de la matriz A y la columna j de la matriz B.

Entonces, para obtener un elemento en un índice particular en la matriz C resultante, deberá calcular el producto escalar de la fila y la columna correspondientes en las matrices A y B, respectivamente.

Repitiendo el proceso anterior, obtendrá la matriz de producto C de forma mxp, con m filas y p columnas, como se muestra a continuación.

Y el producto escalar o el producto interno entre dos vectores a y b viene dado por la siguiente ecuación.

Resumamos ahora:

  • Es evidente que el producto escalar se define solo entre vectores de igual longitud.
  • Entonces, para que el producto punto entre una fila y una columna sea válido, al multiplicar dos matrices, necesitaría que ambas tuvieran la misma cantidad de elementos.
  • En el ejemplo genérico anterior, cada fila de la matriz A tiene n elementos. Y cada columna en la matriz B también tiene n elementos.

Si observa más de cerca, n es el número de columnas en la matriz A, y también es el número de filas en la matriz B. Y esta es precisamente la razón por la que necesita que el número de columnas en la matriz A sea igual al número de filas en la matriz B.

Espero que entiendas la condición para que la multiplicación de matrices sea válida y cómo obtener cada elemento en la matriz producto.

Procedamos a escribir algo de código Python para multiplicar dos matrices.

Escriba una función de Python personalizada para multiplicar matrices

Como primer paso, escribamos una función personalizada para multiplicar matrices.

Esta función debería hacer lo siguiente:

  • Acepte dos matrices, A y B, como entradas.
  • Comprueba si la multiplicación de matrices entre A y B es válida.
  • Si es válido, multiplique las dos matrices A y B, y devuelva la matriz producto C.
  • De lo contrario, devolverá un mensaje de error de que las matrices A y B no se pueden multiplicar.

Paso 1: Genere dos matrices de enteros utilizando la función random.randint() de NumPy. También puede declarar matrices como listas de Python anidadas.

import numpy as np
np.random.seed(27)
A = np.random.randint(1,10,size = (3,3))
B = np.random.randint(1,10,size = (3,2))
print(f"Matrix A:n {A}n")
print(f"Matrix B:n {B}n")

# Output
Matrix A:
 [[4 9 9]
 [9 1 6]
 [9 2 3]]

Matrix B:
 [[2 2]
 [5 7]
 [4 4]]

Paso 2: Continúe y defina la función multiplicar_matrix(A,B). Esta función toma dos matrices A y B como entradas y devuelve la matriz producto C si la multiplicación de matrices es válida.

def multiply_matrix(A,B):
  global C
  if  A.shape[1] == B.shape[0]:
    C = np.zeros((A.shape[0],B.shape[1]),dtype = int)
    for row in range(rows): 
        for col in range(cols):
            for elt in range(len(B)):
              C[row, col] += A[row, elt] * B[elt, col]
    return C
  else:
    return "Sorry, cannot multiply A and B."

Análisis de la definición de la función

Procedamos a analizar la definición de la función.

Declare C como una variable global: de forma predeterminada, todas las variables dentro de una función de Python tienen un alcance local. Y no puede acceder a ellos desde fuera de la función. Para que la matriz de productos C sea accesible desde el exterior, tendremos que declararla como una variable global. Simplemente agregue el calificador global antes del nombre de la variable.

Verifique si la multiplicación de matrices es válida: use el atributo de forma para verificar si A y B se pueden multiplicar. Para cualquier matriz arr, arr.shape[0] y arr.shape[1] dar el número de filas y columnas, respectivamente. Así que si A.shape[1] == forma B[0] comprueba si la multiplicación de matrices es válida. Solo si esta condición es verdadera, se calculará la matriz del producto. De lo contrario, la función devuelve un mensaje de error.

Use bucles anidados para calcular valores: para calcular los elementos de la matriz resultante, tenemos que recorrer las filas de la matriz A, y el bucle for externo hace esto. El ciclo for interno nos ayuda a recorrer la columna de la matriz B. Y el ciclo for interno ayuda a acceder a cada elemento en la columna seleccionada.

▶️ Ahora que hemos aprendido cómo funciona la función Python para multiplicar matrices, llamemos a la función con las matrices A y B que generamos anteriormente.

multiply_matrix(A,B)

# Output
array([[ 89, 107],
       [ 47,  49],
       [ 40,  44]])

Como la multiplicación de matrices entre A y B es válida, la función multiplica_matrix() devuelve la matriz producto C.

Utilice la comprensión de listas anidadas de Python para multiplicar matrices

En la sección anterior, escribió una función de Python para multiplicar matrices. Ahora, verá cómo puede usar comprensiones de listas anidadas para hacer lo mismo.

Aquí está la comprensión de la lista anidada para multiplicar matrices.

Al principio, esto puede parecer complicado. Pero analizaremos la comprensión de la lista anidada paso a paso.

Centrémonos en la comprensión de una lista a la vez e identifiquemos lo que hace.

Usaremos la siguiente plantilla general para la comprensión de la lista:

[<do-this> for <item> in <iterable>]

where,
<do-this>: what you'd like to do—expression or operation
<item>: each item you'd like to perform the operation on
<iterable>: the iterable (list, tuple, etc.) that you're looping through

▶️ Consulte nuestra guía Comprensión de listas en Python, con ejemplos para obtener una comprensión profunda.

Antes de continuar, tenga en cuenta que nos gustaría construir la matriz C resultante una fila a la vez.

Explicación de la comprensión de listas anidadas

Paso 1: Calcular un solo valor en la matriz C

Dada la fila i de la matriz A y la columna j de la matriz B, la siguiente expresión da la entrada en el índice (i, j) en la matriz C.

sum(a*b for a,b in zip(A_row, B_col)

# zip(A_row, B_col) returns an iterator of tuples
# If A_row = [a1, a2, a3] & B_col = [b1, b2, b3]
# zip(A_row, B_col) returns (a1, b1), (a2, b2), and so on

Si i = j = 1, la expresión devolverá la entrada c_11 de la matriz C. De esta manera, puede obtener un elemento en una fila.

Paso 2: construye una fila en la matriz C

Nuestro próximo objetivo es construir una fila completa.

Para la fila 1 en la matriz A, debe recorrer todas las columnas de la matriz B para obtener una fila completa en la matriz C.

Regrese a la plantilla de comprensión de lista.

  • Reemplace con la expresión del paso 1, porque eso es lo que quiere hacer.
  • A continuación, reemplace con B_col: cada columna en la matriz B.
  • Finalmente, reemplace con zip(*B), la lista que contiene todas las columnas en la matriz B.

Y aquí está la primera lista de comprensión.

[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] 

# zip(*B): * is the unzipping operator
# zip(*B) returns a list of columns in matrix B

Paso 3: construye todas las filas y obtén la matriz C

A continuación, deberá completar la matriz de productos C calculando el resto de las filas.

Y para esto, debe recorrer todas las filas en la matriz A.

Vuelva a la lista de comprensión una vez más y haga lo siguiente.

  • Reemplace con la lista de comprensión del paso 2. Recuerde que calculamos una fila completa en el paso anterior.
  • Ahora, reemplace con A_row—cada fila en la matriz A.
  • Y su es la propia matriz A, mientras recorre sus filas.

Y aquí está nuestra comprensión final de la lista anidada.🎊

[[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] 
    for A_row in A]

¡Es hora de verificar el resultado! ✔

# cast into <a href="https://kirukiru.es.com/numpy-reshape-arrays-in-python/">NumPy array</a> using np.array()
C = np.array([[sum(a*b for a,b in zip(A_row, B_col)) for B_col in zip(*B)] 
    for A_row in A])

# Output:
[[ 89 107]
 [ 47  49]
 [ 40  44]]

Si observa más de cerca, esto es equivalente a los bucles for anidados que teníamos antes, solo que es más breve.

También puede hacer esto de manera más eficiente utilizando algunas funciones integradas. Aprendamos sobre ellos en la siguiente sección.

Use NumPy matmul() para multiplicar matrices en Python

El np.matmul() toma dos matrices como entrada y devuelve el producto si la multiplicación de matrices entre las matrices de entrada es válida.

C = np.matmul(A,B)
print(C)

# Output:
[[ 89 107]
 [ 47  49]
 [ 40  44]]

Observe cómo este método es más simple que los dos métodos que aprendimos anteriormente. De hecho, en lugar de np.matmul(), puede usar un operador @ equivalente, y lo veremos de inmediato.

Cómo usar el operador @ en Python para multiplicar matrices

En Python, @ es un operador binario utilizado para la multiplicación de matrices.

Opera en dos matrices y, en general, matrices NumPy N-dimensionales, y devuelve la matriz del producto.

Nota: debe tener Python 3.5 y versiones posteriores para usar el operador @.

Así es como puedes usarlo.

C = [email protected]
print(C)

# Output
array([[ 89, 107],
       [ 47,  49],
       [ 40,  44]])

Observe que la matriz de productos C es la misma que obtuvimos anteriormente.

¿Puedes usar np.dot() para multiplicar matrices?

Si alguna vez se encontró con un código que usa np.dot() para multiplicar dos matrices, así es como funciona.

C = np.dot(A,B)
print(C)

# Output:
[[ 89 107]
 [ 47  49]
 [ 40  44]]

Verá que np.dot(A, B) también devuelve la matriz del producto esperado.

Sin embargo, según documentos numpydebe usar np.dot() solo para calcular el producto escalar de dos vectores unidimensionales y no para la multiplicación de matrices.

Recuerde de la sección anterior, el elemento en el índice (i, j) de la matriz de productos C es el producto escalar de la fila i de la matriz A y la columna j de la matriz B.

Como NumPy transmite implícitamente esta operación de producto escalar a todas las filas y columnas, obtienes la matriz de producto resultante. Pero para mantener su código legible y evitar la ambigüedad, use np.matmul() o el operador @ en su lugar.

Conclusión

🎯 En este tutorial, has aprendido lo siguiente.

  • Condición para que la multiplicación de matrices sea válida: número de columnas en la matriz A = número de filas en la matriz B.
  • Cómo escribir una función de Python personalizada que verifique si la multiplicación de matrices es válida y devuelva la matriz del producto. El cuerpo de la función utiliza bucles for anidados.
  • A continuación, aprendió a usar comprensiones de listas anidadas para multiplicar matrices. Son más breves que los bucles for pero son propensos a problemas de legibilidad.
  • Finalmente, aprendió a usar la función incorporada de NumPy np.matmul() para multiplicar matrices y cómo esto es lo más eficiente en términos de velocidad.
  • También aprendiste sobre el operador @ para multiplicar dos matrices en Python.

Y eso concluye nuestra discusión sobre la multiplicación de matrices en Python. Como siguiente paso, aprenda cómo verificar si un número es primo en Python. O resolver problemas interesantes en cadenas de Python.

¡Feliz aprendizaje!🎉