Autor: Luis Fernando Apáez Álvarez
-Curso PyM-
Tarea 7: Librería NumPy
Fecha de Entrega: 03 de Septiembre del 2022
Descripción: En esta tarea pondremos en práctica lo aprendido sobre los arrays de NumPy, para lo cual extraeremos una imagen de la web y la convertiremos en un array. Asimismo, indagaremos un poco sobre álgebra lineal, donde veremos el concepto de matriz inversa y el determinante de una matriz, de nuevo estaremos ocupando la librería NumPy.
(Tiempo estimado: 30 minutos)
Las imágenes pueden considerarse como un array de pixeles
donde las entradas de dicho array son números que hacen alusión a una escala de colores. Por ejemplo, para el caso en el que trabajamos con píxeles de 8 bits (es decir con un rango de números del 0 al 255), tendremos entonces que cada píxel admite hasta 256 variaciones de color
y donde cada color anterior estará representado por un número del 0 al 255.
Ahora bien, lo que haremos será convertir una imagen cualquiera en un array mediante la librería NumPy, pero antes veremos cómo cargar una imagen de la web en una variable de Python, para lo cual nos valdremos de las librerías PIL y request.
# De la libreria PIL importamos Image
from PIL import Image
# Importamos la libreria request la cual se utiliza para
# realizar solicitudes HTTP en Python
import requests
# En la variable url guardamos la direccion de la imagen
# con la cual queremos trabajar
url = r'https://luisapaez.github.io/Teoria_Galois/bob.png'
# Mediante Image.open() abriremos una imagen la cual
# obtendremos de la url antes escrita
im = Image.open(requests.get(url, stream=True).raw)
# Veamos cual imagen obtuvimos
display(im)
Puedes indagar más sobre las librerías antes ocupada en los siguientes links:
Ahora bien, la variable im
almacena la imagen que obtuvimos, y lo que haremos será convertir dicha imagen a un array NumPy, donde dicho array contendrá valores del 0-255 que hacen alusión a los colores de todos los píxeles de la imagen
# COMPLETA SEGUN SE TE INDIQUE
# Realiza la importacion de al libreria numpy
# y asignale el alias de np
_ _ _
# Convertimos la imagen en un array
array = np.array(im)
# Obtengamos la forma de dicho array
print(array._ _ _)
# Veamos como es dicho array
array
donde vemos al final dtype=uint8
que nos dice que el tipo de dato de los valores del array son enteros no negativos de 8 bits.
Después, crearemos un array auxiliar cuyas entradas sean todas igual al 100 y que posea la misma forma que el array array
:
# Creamos un array de la misma forma que array
# donde el 100 sera el valor asignado a
# todas las entradas
array_aux = np._ _ _ (array.shape, 100)
array_aux
Si nosotros modificamos los valores de las entradas del array array
, entonces los colores de la imagen serán modificados también. Lo que haremos será sumar, entrada a entrada, el array array
con el array array_aux
.
# Realizamos la suma antes dicha
array_modificado = _ _ _
# Establecemos el tipo de dato de nuestro array
# modificado a enteros no negativos de 8 bits
array_modificado = array_modificado.astype(np.uint8)
# Veamos nuestro array
array_modificado
Para ver la imagen proveniente de un array utilizamos Image.fromarray()
como sigue
# Ejecuta esta celda:
# Veamos la imagen resultante proveniente del array
# array_modificado
display(Image.fromarray(array_modificado))
Dada una matriz cuadrada, es decir que el número de filas y columnas es el mismo, podemos obtener su matriz inversa (en algunos casos), donde se debe de cumplir que la multiplicación matricial de dicha matriz con su matriz inversa debe dar como resultado una matriz identidad. Cabe resaltar que la multiplicación matricial no es aquella en la que se multiplican los valores de las matrices entrada a entrada.
Por un lado, podemos multiplicar arrays entrada a entrada utilizando el operador *
como sigue
array1 = np.array([[1, 3],
[5, 0]])
# Creamos un array de dos filas con dos columnas
# cuyos valores solo sean el numero 1
array2 = np._ _ _ ((2,2))
# Realizamos la multiplicacion de dichos arrays
array1 * array2
donde dicha multiplicación fue realizada entrada a entrada. La multiplicación matricial no es entrada a entrada. Por ejemplo, multipliquemos dos matrices cuadradas de 2x2 cualesquiera:
$$ \left(\begin{array}{cc} a& b\\ c& d \end{array}\right)\left(\begin{array}{cc} e& f\\ g& h \end{array}\right)=\left(\begin{array}{cc} ae+bg & af+bh\\ ce+dg & cf+dh \end{array}\right) $$La multiplicación matricial la obtenemos en NumPy utilizando np.dot()
. Por ejemplo, de los arrays que definimos antes (array1
y array2
), podemos multiplicarlos:
# Multiplicacion "matricial" mediante
# np.dot()
np.dot(array1, array2)
Ahora bien, cada matriz tiene asociado un número, el cual se denomina determinante, y que nos ayuda a saber si una matriz tiene inversa o no. Por ejemplo, de la matriz
$$ \left(\begin{array}{cc} a& b\\ c& d \end{array}\right) $$su determinante es el número $det = ad-bc$. Si $det\neq 0$, entonces la matriz sí tiene matriz inversa, si $\det=0$, entonces la matriz no tiene inversa. Podemos obtener el determinante de un array utilizando np.linalg.det()
como sigue
# Determinante de array1
print(np.linalg.det(array1))
print()
# Determinante de array2
print(np._ _ _ (array2))
Tenemos entonces que el array1
sí tiene matriz inversa y el array array2
no.
Ahora bien, dada la matriz
$$ \left(\begin{array}{cc} a& b\\ c& d \end{array}\right) $$si $det\neq0$, entonces la matriz inversa está dada por
$$ \frac{1}{det}\left(\begin{array}{cc} d& -b\\ -c& a \end{array}\right) $$Por ejemplo, considerando el array
$$ \left(\begin{array}{cc} 1& 3\\ 5& 0 \end{array}\right) $$dado que $det=-15\neq0$ entonces dicho array tiene matriz inversa, la cual está dada por
$$ \frac{1}{-15}\left(\begin{array}{cc} 0&-3\\ -5& 1 \end{array}\right)=\left(\begin{array}{cc} 0 &\frac{-3}{-15}\\ \frac{-5}{-15}& \frac{1}{-15} \end{array}\right)=\left(\begin{array}{cc} 0 &\frac{1}{5}\\ \frac{1}{3}& \frac{1}{-15} \end{array}\right)=\left(\begin{array}{cc} 0 &0.2\\ 0.3333& -0.0666 \end{array}\right) $$Para obtener la matriz inversa de un array escribimos np.linalg.inv()
. Por ejemplo:
# "Matriz" inversa del array1
np.linalg.inv(array1)
Recordemos que al inicio se dijo que, la multiplicar una matriz con su matriz inversa el resultado es una matriz identidad, veamos que dicha propiedad se está cumpliendo
# Definimos un array referente a la matriz identidad
# del array1
array1_inv = np.linalg.inv(array1)
# Multiplicamos el array anterior con el array1 (multiplicacion
# matricial)
_ _ _