BioData Insights

Fundamentos de NumPy para Análisis de Datos

Aprende a usar arrays de NumPy para realizar cálculos numéricos eficientes. Cubriremos operaciones vectorizadas y técnicas de normalización, fundamentales para la preparación de datos biológicos.

NumPy: La Base para la Computación Numérica de Alto Rendimiento

NumPy (Numerical Python) es la biblioteca fundamental para la computación científica en Python. Introduce un objeto de datos clave: el array de NumPy (ndarray). Este objeto es similar a una lista de Python, pero con dos superpoderes: es mucho más rápido y mucho más eficiente en el uso de memoria para operaciones numéricas.

¿Por qué es tan rápido? Porque los arrays de NumPy son homogéneos (todos los elementos son del mismo tipo) y están almacenados en un bloque de memoria contiguo. Esto permite que NumPy realice operaciones utilizando código C o Fortran altamente optimizado en segundo plano. La mayoría de las bibliotecas de ciencia de datos, como Pandas, están construidas sobre NumPy, por lo que dominarlo es esencial para escribir código de análisis de datos eficiente.


# Nota: Este código está listo para ser copiado y ejecutado en un notebook de Google Colab.

# Por convención, siempre importamos la biblioteca NumPy con el alias 'np'.
# Esto hace que nuestro código sea más corto y siga un estándar reconocido.
import numpy as np

# Creamos un array de NumPy a partir de una lista de Python.
# Imaginemos que estos son los niveles de expresión de un gen en 5 muestras distintas.
lista_python = [1.2, 3.4, 2.8, 5.1, 4.2]
niveles_expresion = np.array(lista_python)

# Al imprimir el array, vemos que se muestra de forma compacta y sin comas.
print("Array de NumPy:", niveles_expresion)
# >> Salida: Array de NumPy: [1.2 3.4 2.8 5.1 4.2]

# Podemos verificar el tipo del objeto, que es 'numpy.ndarray'.
print("Tipo de objeto:", type(niveles_expresion))
# >> Salida: Tipo de objeto: <class 'numpy.ndarray'>

# Las funciones de NumPy operan sobre arrays completos de forma muy eficiente.
# En lugar de escribir un bucle para calcular la media, usamos np.mean().
media_expresion = np.mean(niveles_expresion)
desviacion_estandar = np.std(niveles_expresion) # Igualmente para la desviación estándar.

print(f"Expresión media: {media_expresion:.2f}") # Formateamos a 2 decimales
# >> Salida: Expresión media: 3.34
print(f"Desviación estándar: {desviacion_estandar:.2f}")
# >> Salida: Desviación estándar: 1.42
Operaciones Vectorizadas y Normalización de Datos

La gran ventaja de NumPy es su capacidad para realizar operaciones vectorizadas. Esto significa que podemos aplicar una operación matemática a cada elemento de un array sin necesidad de escribir un bucle for. Esto no solo hace el código más limpio y legible, sino que es órdenes de magnitud más rápido porque las iteraciones ocurren en código C compilado, no en Python.

Un uso práctico y fundamental en bioinformática y fitopatología es la normalización de datos. A menudo, los datos biológicos vienen en diferentes escalas (p.ej., la expresión de un gen puede estar en miles, mientras que la concentración de un metabolito está en microgramos). La normalización ajusta estos valores a una escala común (por ejemplo, de 0 a 1), lo cual es crucial para comparar mediciones y para que muchos algoritmos de aprendizaje automático funcionen correctamente.


# Nota: Este código está listo para ser copiado y ejecutado en un notebook de Google Colab.

# Importamos numpy con el alias np.
import numpy as np

# Creamos un array que representa el número de lesiones por hoja en 5 plantas diferentes.
# Estos son nuestros datos "crudos" o sin procesar.
lesiones_por_hoja = np.array([10, 20, 5, 45, 15])
print("Datos originales:", lesiones_por_hoja)
# >> Salida: Datos originales: [10 20  5 45 15]

# --- Operación Vectorizada Simple ---
# Supongamos que queremos convertir el número de lesiones a una estimación de área dañada,
# asumiendo que cada lesión mide 0.5 cm². No necesitamos un bucle.
area_danada_cm2 = lesiones_por_hoja * 0.5
print("Área dañada estimada (cm²):", area_danada_cm2)
# >> Salida: Área dañada estimada (cm²): [ 5.  10.   2.5 22.5  7.5]

# --- Normalización Min-Max ---
# Esta técnica escala los datos a un rango de [0, 1].
# La fórmula es: X_norm = (X - X_min) / (X_max - X_min)

# NumPy nos permite hacerlo de forma vectorizada y eficiente.
minimo_lesiones = np.min(lesiones_por_hoja) # Hallamos el valor mínimo del array (5).
maximo_lesiones = np.max(lesiones_por_hoja) # Hallamos el valor máximo del array (45).

print(f"Valor mínimo: {minimo_lesiones}, Valor máximo: {maximo_lesiones}")
# >> Salida: Valor mínimo: 5, Valor máximo: 45

# Aplicamos la fórmula de normalización a todo el array a la vez.
# NumPy resta el mínimo a cada elemento, y luego divide cada resultado por el rango.
rango = maximo_lesiones - minimo_lesiones
datos_normalizados = (lesiones_por_hoja - minimo_lesiones) / rango

# Los datos normalizados ahora están en una escala de 0 a 1.
# El valor más bajo (5) se convierte en 0, y el más alto (45) se convierte en 1.
print("Datos normalizados (escala 0-1):", datos_normalizados)
# >> Salida: Datos normalizados (escala 0-1): [0.125 0.375 0.    1.    0.25 ]