En este tutorial, aprenderá cómo 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 utilizar 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 matriz A is igual de las personas acusadas injustamente llamadas número de filas en 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

matriz-multiplicar

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

matriz-producto

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

producto escalado

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 en la matriz A tiene n elementos. Y cada columna en la matriz B tiene n elementos también.

Si miras 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 el número de columnas en matriz A para ser igual de las personas acusadas injustamente llamadas número de filas en 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.

Write a Custom Python Function to Multiply 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 usando NumPy's random.randint() función. 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. multiply_matrix(A,B). Esta función toma dos matrices A y B como entradas y devuelve la matriz del 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.

Declarar C como una variable global: Por defecto, todas las variables dentro de una función de Python tienen 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. Solo agrega el global calificador antes del nombre de la variable.

Comprueba si la multiplicación de matrices es válida: Utilice el shape atributo para verificar si A y B se pueden multiplicar. Para cualquier matriz arr, arr.shape[0] y arr.shape[1] dar el numero de filas y columnas respectivamente. Asi que if A.shape[1] == B.shape[0] comprueba si la multiplicación de matrices es válida. Sólo si esta condición es True, 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 exterior for bucle hace esto. El interior for loop nos ayuda a recorrer la columna de la matriz B. Y el más interno for loop 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 multiply_matrix() devuelve la matriz producto C.

Use Python Nested List Comprehension to Multiply 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.

lista-anidada-comprensión-matriz-multiplicar

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 Lista de comprensión en Python - con ejemplos para obtener una comprensión profunda.

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

Explicación de la comprensión de listas anidadas

Paso 1: Calcule 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

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

Paso 2: Construya 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.

  • Replace <do-this> con la expresión del paso 1, porque eso es lo que quieres hacer.
  • A continuación, reemplace <item> con B_col—cada columna en la matriz B.
  • Finalmente, reemplace <iterable> con zip(*B)—la lista que contiene todas las columnas de 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: Construya todas las filas y obtenga 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.

  • Replace <do-this> con la lista de comprensión del paso 2. Recuerda que calculamos una fila completa en el paso anterior.
  • Ahora, reemplace <item> con A_row—cada fila en la matriz A.
  • Y tu <iterable> es la propia matriz A, mientras recorres 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 NumPy array 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() to Multiply Matrices in Python

Los np.matmul() toma dos matrices como entrada y devuelve el producto si la multiplicación de matrices entre las matrices de entrada es IMPORTANTE.

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: Necesitas 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 te has encontrado 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ás eso np.dot(A, B) también devuelve la matriz del producto esperado.

Sin embargo, según Documentos de NumPy, Deberías usar np.dot() solo para calcular el producto punto 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 @ 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 matriz A = número de filas en 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 a verificar si un número es primo en Python. O resolver interesantes problemas en cadenas de Python.

¡Feliz aprendizaje!🎉