Primeros Pasos con NumPy

PyLadies Cuernavaca

6/28/24

¿Qué es NumPy?

«Numerical Python». Nos permite realizar análisis matemáticos o calculos complejos en Python.

¿Qué es NumPy?

«Numerical Python». Nos permite realizar análisis matemáticos o calculos complejos en Python. Como:Transformadas de Furier, Análisis estadísticos como: Permutaciones, combinaciones, algebra lineal…etc.

\[\begin{array}{cc} \mathbf{A} = \begin{pmatrix} a_{11} & a_{12} & a_{13} \\ a_{21} & a_{22} & a_{23} \\ a_{31} & a_{32} & a_{33} \end{pmatrix} & \mathbf{v} = \begin{pmatrix} v_1 \\ v_2 \\ v_3 \end{pmatrix} \end{array}\]

\[ \hat{f}(k) = \int_{-\infty}^{\infty} f(x) e^{-2\pi i k x} \, dx \]

¿Qué es NumPy?

importante

Es posible que escuches términos como “escalar” para un array 0-D, “vector” para un array 1-D, “matriz” para un array 2-D y “tensor” para un array N-D (donde N es mayor que 2). Sin embargo, para mayor claridad, es mejor evitar estos términos matemáticos al referirse a arrays, ya que los objetos matemáticos con estos nombres se comportan de manera diferente a los arrays.

¿Para qué se ha utilizado NumPy?

¿Qué es NumPy?

¿Qué es NumPy?

¿Qué es NumPy?

Numpy Es la base del ecosistema científico de Python, ofreciendo una estructura de arrays multidimensionales y funciones de cálculo vectorizado que facilitan el análisis y la manipulación de datos científicos

Listas y Numpy

Listas

a = [1,2,3]
b = [2,3,4]

a*b # ESTO MARCA ERROR

NumPy Arrays

a = np.array([1,2,3])
b = np.array([3,4,5])
# vayan a colab
a*b 

Python nativo vs NumPy

# Crear una matriz 3D de tamaño 3x3x3 con Python nativo
matrix_3d = [[[0 for _ in range(3)] for _ in range(3)] for _ in range(3)]
# Sumar 1 a cada elemento
for i in range(3):
    for j in range(3):
        for k in range(3):
            matrix_3d[i][j][k] += 1
print(matrix_3d)


# Crear una matriz 3D de tamaño 3x3x3 con NumPy
matrix_3d = np.zeros((3, 3, 3))
matrix_3d += 1 # Sumar 1 a cada elemento
print(matrix_3d)

Important

La mayoría de los arrays de NumPy tienen algunas restricciones. Por ejemplo:

  • Todos los elementos del array deben ser del mismo tipo de datos.
  • Una vez creado, el tamaño total del array no puede cambiar.
  • La forma debe ser “rectangular”, no “dentada”; por ejemplo, cada fila de un array bidimensional debe tener el mismo número de columnas.

Note

En resumen, los arrays de NumPy tienen un tamaño fijo después de su creación, lo que implica que no pueden ser redimensionados directamente, aunque puedes crear nuevos arrays con tamaños diferentes y copiar los datos si es necesario.




Vamos a

NumPy

¿Cómo importar NumPy?

Después de instalar NumPy, puede importarse en el código Python de la siguiente manera:

 pip install numpy
 import numpy as np
 print(np.__version__)

Entonces podemos acceder a las características de NumPy con el prefijo np

#sintáxis
#np.array(object, dtype=None, copy=True...)

un_vector = [5,12,16] #o lista
a = np.array(un_vector)
b = np.array([[1, 2, 3],
              [4, 5, 6]]) # lista de lista
b.shape
#(2, 3)
#b = np.arange(16).reshape(4, 4)
#b

Algunas funciones/métodos de NumPy

np.ones(3)
np.zeros(3)
np.random.random(3)
np.random.random(size=None)

arr = np.empty((2, 3))
print(arr)
# Output:
# [[1. 2. 3.]
#  [4. 5. 6.]] (Valores pueden variar)

#Supongamos que deseas simular datos de expresión génica aleatoria para 100 genes en 5 condiciones diferentes. Puedes utilizar np.random.random para generar estos datos.
# Generar datos de expresión génica aleatoria
expresion_genica = np.random.random((100, 5))
print(expresion_genica)
# Output: una matriz 100x5 con valores aleatorios en el intervalo [0.0, 1.0)

Algunas funciones/métodos de NumPy

Algunas funciones/métodos de NumPy

np.multiply

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
np.multiply(a, b)
# array([ 4, 10, 18])
a = np.array([1, 2, 3])
escalar = 2
resultado = np.multiply(a, escalar)
print(resultado)
# Output: [2 4 6]

#Especificando el tipo de salida

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
resultado = np.multiply(a, b, dtype=float)
print(resultado)

Algunas funciones/métodos de NumPy

Function name NaN-safe version Description
np.sum np.nansum Compute sum of elements
np.prod np.nanprod Compute product of elements
np.mean np.nanmean Compute mean of elements
np.std np.nanstd Compute standard deviation
np.var np.nanvar Compute variance
np.min np.nanmin Find minimum value
np.max np.nanmax Find maximum value
np.argmin np.nanargmin Find index of minimum value
np.argmax np.nanargmax Find index of maximum value
np.median np.nanmedian Compute median of elements
np.percentile np.nanpercentile Compute rank-based statistics of elements
np.any N/A Evaluate whether any elements are true
np.all N/A Evaluate whether all elements are true

spoiler alert!

Arange - más dimensiones….

np.arange([start,] stop[, step,], dtype=None, *, like=None)

np.array([[1,2],[3,4]])
b = np.arange(16).reshape(4, 4)

np.tile

x = np.array([3, 5, 7])
np.tile(x, 3)
array([3, 5, 7, 3, 5, 7, 3, 5, 7])
np.tile(x, (3,3))
array([[3, 5, 7, 3, 5, 7, 3, 5, 7],
       [3, 5, 7, 3, 5, 7, 3, 5, 7],
       [3, 5, 7, 3, 5, 7, 3, 5, 7]])

Diferencia entre tile y repeat

array = np.array([1, 2, 3])

# np.repeat(): Repite cada elemento
repeated_array = np.repeat(array, 2)
print("np.repeat():", repeated_array)
# Output: [1 1 2 2 3 3]

# np.tile(): Repite la estructura completa del array
tiled_array = np.tile(array, 2)
print("np.tile():", tiled_array)
# Output: [1 2 3 1 2 3]

a = np.array[[9.0,0.8,0.3],[7.2,3.2,4.1]]
o = a.astype('int') ##también puedes convertir a enteros... o o = a.astype('bool')

o = np.linspace(0, 100, 5) # este incluye al 100, da 5 saltos desde el 0 hasta el 100

full_array = np.full((2, 2), 5)  # Array de 2x2 lleno de 5s
empty_array = np.empty((2, 2))  # Array de 2x2 con valores no inicializados

a.ndim # numero dimensiones
a = np.array([[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]])
print(a.ndim)  # Output: 4

a.shape #Devuelve una tupla que indica el tamaño de cada dimensión del array 
a.dtype #Devuelve el tipo de datos de los elementos del array a.
# Output: int64 (o el tipo de dato específico en tu sistema)
a.size # Devuelve el número total de elementos en el array a
a = np.array([[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]])
print(a.size)  # Output: 8

a.nbytes # Devuelve el número total de bytes utilizados por los elementos del array a.
a = np.array([[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]])
print(a.nbytes)  # Output: 64 (8 elementos * 8 bytes por elemento, asumiendo int64)

a = np.array([[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]])

print("Número de dimensiones:", a.ndim)  # Output: 4
print("Forma del array:", a.shape)       # Output: (1, 2, 2, 2)
print("Tipo de datos:", a.dtype)         # Output: int64
print("Número total de elementos:", a.size)  # Output: 8
print("Número total de bytes:", a.nbytes)    # Output: 64

# cuidado con los datos heterogéneos... ahí se ocupa el tipo objeto PERO ya no se pueden tratar para las mismas operaciones matemáticas y estadísticas

Algunas funciones/métodos de NumPy

Los elementos de un array pueden accederse de varias maneras.Por ejemplo, podemos acceder a un elemento individual de este tipo de array como accederíamos a un elemento en la lista original: usando el índice entero del elemento dentro de corchetes.

data = [1,2,3]
data[0]
data[0] = 40

Indexación Avanzada y Slicing

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# Seleccionar elementos mayores que 5
bool_index = arr > 5
filtered_array = arr[bool_index]
print(filtered_array)  # Output: [6, 7, 8, 9]


arr = np.array([10, 20, 30, 40, 50])

# Seleccionar elementos usando una lista de índices
indices = [0, 2, 4]
selected_elements = arr[indices]
print(selected_elements)  # Output: [10, 30, 50]

a = np.array([1,2,3,4,5])
b = np.array([1,3,2,4,5])

print(np.where(a == b)) # imprime los indices donde los elementos coinciden en a y b

a[:3]
array([10, 2, 3])

Indexación Avanzada y Slicing

import numpy as np

# Crear un array 2D
arr = np.array([[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]])

# Acceder a un elemento específico
print(arr[1, 2])  # Output: 6 (fila 1, columna 2)

# Acceder a una fila completa
print(arr[0])  # Output: [1 2 3] (primera fila)

# Acceder a una columna completa
print(arr[:, 1])  # Output: [2 5 8] (segunda columna)

# Acceder a un subarray
print(arr[1:, :2])  # Output: [[4 5]
                    #          [7 8]] (filas 1 y 2, columnas 0 y 1)


# Crear un array 2D
arr = np.array([[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]])

# Definir listas de índices para filas y columnas
filas = [0, 2]
columnas = [0, 2]

# Acceder a elementos usando las listas de índices
seleccionados = arr[filas, columnas]
print(seleccionados)
# Output: [1 9]
arr = np.array([10, 20, 30, 40, 50])

# Crear una máscara booleana
mascara = np.array([True, False, True, False, True])

# Seleccionar elementos basados en la máscara booleana
seleccionados = arr[mascara]
print(seleccionados)

Para asignar valores

arr = np.array([1, 2, 3, 4, 5])

# Definir una lista de índices para asignación
indices = [1, 3]

# Asignar nuevos valores a los elementos seleccionados
arr[indices] = 0
print(arr)
# Output: [1 0 3 0 5]

Hora del Quiz

https://www.menti.com/al2gu1v47yj8

Recursos

PyLadies-Cuernavaca