Volver a la lista

Organizar datos de experimentos con Pandas.

Cómo leer, filtrar y obtener estadísticas por grupo de datos experimentales CSV con un DataFrame de Pandas.

Intermedio
|
90min
|
Verificado (2026-06)
pandasDataFrameCSVLimpieza de datos.groupbymerge
Progreso0/12 (0%)

Organizar datos experimentales con Pandas

Al finalizar este tema

Podrás leer un archivo CSV en un DataFrame de Pandas, realizar filtrados condicionales, obtener estadísticas por grupo y combinar dos tablas.


¿Qué es Pandas?

En el tema anterior, aprendiste a leer archivos con el módulo csv y a procesarlos con bucles. Esto es suficiente si tienes 10 muestras, pero si tienes 5000 muestras y 50 columnas, los bucles se vuelven ineficientes.

Pandas es una biblioteca de Python para trabajar con datos tabulares. Permite almacenar datos en una estructura llamada DataFrame, similar a una hoja de cálculo de Excel, y realizar filtrados, ordenamientos y agregaciones con una sola línea de código.

Si lo comparamos con un cuaderno de laboratorio, el módulo csv sería como leer el cuaderno línea por línea, mientras que Pandas sería como tener toda la tabla a la vista y poder extraer las columnas o filas que necesitas de inmediato.

Crear un DataFrame

python
import pandas as pd
df = pd.read_csv("expression_data.csv")
print(df)
print(f"\nFilas: {len(df)}, columnas: {len(df.columns)}")
print(f"Columnas: {list(df.columns)}")

pd.read_csv() Un archivo CSV se convierte en un DataFrame con una sola línea. Todos los datos se cargan sin necesidad de csv.DictReader ni bucles.

También puede crear los datos directamente:

python
import pandas as pd
data = {
"sample_id": ["S001", "S002", "S003", "S004", "S005"],
"gene": ["EGFR", "TP53", "EGFR", "BRCA1", "TP53"],
"expression": [12.5, 3.2, 18.7, 7.1, 2.8],
"status": ["high", "low", "high", "medium", "low"],
}
df = pd.DataFrame(data)
print(df)

Salida:

text
sample_id   gene  expression  status
0      S001   EGFR        12.5    high
1      S002   TP53         3.2     low
2      S003   EGFR        18.7    high
3      S004  BRCA1         7.1  medium
4      S005   TP53         2.8     low

Exploración de los datos

Cuando se recibe un DataFrame por primera vez, es importante obtener una visión general rápida de su estructura:

python
df.head() # Primeras 5 filas
df.tail(3) # Últimas 3 filas
df.shape # (número de filas, número de columnas)
df.dtypes # Tipo de datos de cada columna
df.describe() # Estadísticas básicas de las columnas numéricas (media, desviación estándar, mínimo y máximo)

df.describe() es útil para tener una idea general del rango de los resultados experimentales cuando se reciben por primera vez.

Selección de columnas/filas

python
# Seleccionar una columna — devuelve una Series
genes = df["gene"]
# Seleccionar varias columnas — devuelve un DataFrame
subset = df[["sample_id", "expression"]]
# Seleccionar filas — por índice
first_row = df.iloc[0] # Primera fila
first_three = df.iloc[0:3] # Filas 0 a 2

Filtrado condicional

Es una de las funciones principales de Pandas. Permite realizar en una sola línea lo que antes se hacía en dos líneas en el módulo csv: for y if.

python
# Solo el gen EGFR
egfr = df[df["gene"] == "EGFR"]
print(egfr)
# Muestras con expression mayor o igual que 5
high_expr = df[df["expression"] >= 5.0]
print(high_expr)
# Condición compuesta: EGFR y expression mayor o igual que 15
egfr_high = df[(df["gene"] == "EGFR") & (df["expression"] >= 15.0)]
print(egfr_high)
assert len(egfr) == 2
assert len(egfr_high) == 1

& es AND, | es OR. Cada condición debe estar entre paréntesis.

Ordenar

python
# expression en orden descendente
sorted_df = df.sort_values("expression", ascending=False)
print(sorted_df)

Agrupación por grupos: groupby

"¿Cuál es la expresión media por gen?" — En Excel, esto se hacía con tablas dinámicas; ahora se hace con groupby:

python
gene_stats = df.groupby("gene")["expression"].agg(["mean", "std", "count"])
print(gene_stats)

Salida:

text
mean       std  count
gene
BRCA1   7.10       NaN      1
EGFR   15.60  4.384062      2
TP53    3.00  0.282843      2

groupby("gene") — Agrupar por gen, ["expression"] — para la columna de expresión, agg(["mean", "std", "count"]) — calcular la media, la desviación estándar y el recuento de una sola vez.

Agregar una nueva columna

python
# Añadir una columna con expression transformada a log2
import numpy as np
df["log2_expression"] = np.log2(df["expression"])
print(df[["sample_id", "expression", "log2_expression"]])

Combinar dos tablas: merge

Cuando los datos del experimento y la información de la muestra se encuentran en archivos separados:

python
import pandas as pd
# Metadatos de las muestras
metadata = pd.DataFrame({
"sample_id": ["S001", "S002", "S003", "S004", "S005"],
"tissue": ["lung", "breast", "lung", "breast", "colon"],
"age": [45, 62, 38, 55, 71],
})
# Combinar con los datos de expression
merged = pd.merge(df, metadata, on="sample_id")
print(merged)

on="sample_id" — Combina filas que tienen el mismo valor en dos tablas. Es un concepto similar a JOIN en SQL. Lo que aprendiste en el tema database-basics también se aplica aquí.

Guardar los resultados

python
# Guardar como CSV
egfr.to_csv("egfr_samples.csv", index=False)
# Guardar como TSV
egfr.to_csv("egfr_samples.tsv", sep="\t", index=False)

index=False — No se incluirán los números de fila (0, 1, 2...) en el archivo.

¡Pruébalo tú mismo! (Ejemplo simplificado)

Completa los espacios en blanco para realizar un filtrado condicional y una agregación de grupos en el DataFrame.

Completar espaciospython
import pandas as pd
df = pd.read_csv("samples.csv")
# Filtrar las muestras con un valor de OD mayor o igual a 1.0
passed = df[df["od"] 1.0]
# OD medio por estado
stats = df.("status")["od"].mean()
print(stats)

Errores comunes y soluciones

P: Me sale el error KeyError: 'gene'

Comprueba que el nombre de la columna sea correcto. Usa df.columns para imprimir los nombres de las columnas reales. Puede que contenga espacios (" gene" vs "gene").

P: He filtrado los datos y he obtenido un DataFrame vacío

Es posible que la condición sea demasiado estricta o que el tipo de datos no sea el correcto. Usa df["expression"].dtype para comprobar el tipo. Si comparas una cadena con un número, es posible que no obtengas resultados.

P: Me sale la advertencia SettingWithCopyWarning

Esta advertencia aparece cuando asignas un valor al resultado filtrado. Crea una copia explícita con df_filtered = df[condición].copy() y modifícala para que la advertencia desaparezca.

P: He hecho merge y el número de filas ha aumentado

Si la columna especificada en on tiene valores duplicados, se crearán todas las combinaciones posibles, lo que aumentará el número de filas. Antes de merge, comprueba si hay duplicados en ambas tablas con df["sample_id"].duplicated().sum().

💬 Preguntas y comentarios

0 comentarios

Puedes publicar sin iniciar sesión. Los comentarios de invitados no pueden editarse ni eliminarse después.

0/2000

Cargando...