Muestreo estratificado con Python y pandas

Resumen

El muestreo estratificado en Python te permite crear submuestras representativas cuando tu base de datos no refleja las proporciones reales de la población. Si trabajas con datos de turismo, comercio o cualquier dataset con categorías mezcladas, esta técnica te ayuda a corregir desbalances y obtener resultados confiables.

La idea central es simple: divides los datos en grupos homogéneos y exclusivos (los estratos) y luego extraes una muestra aleatoria respetando la proporción deseada de cada grupo. Vamos a verlo paso a paso usando un dataset de establecimientos económicos de la Ciudad de México.

¿Cómo se crea la variable de estratificación en pandas?

Antes de muestrear necesitas definir el criterio que separa tus estratos. En este ejemplo combinamos dos columnas: delegacion (ubicación) y tipo (hotel, museo, mercado, etc.).

python econdata['estratificado'] = econdata['delegacion'] + ',' + econdata['tipo'] econdata['estratificado'].value_counts() / len(econdata)

El value_counts dividido entre la longitud total te devuelve la proporción real de cada estrato. En el dataset original, los hoteles en Cuauhtemoc representan el 64.34%, seguidos de museos y hoteles en Venustiano Carranza.

¿Qué es el muestreo estratificado? Es una técnica que divide la población en grupos homogéneos y exclusivos llamados estratos, y luego toma una muestra aleatoria de cada uno respetando proporciones definidas.

Un detalle importante: la fuente original escribe Cuauhtemoc sin la h. No corrijas el dato en el código si quieres que coincida con la base; reserva la corrección para tus conclusiones finales [01:55].

¿Cómo defines las proporciones deseadas para tu muestra?

Aquí está el ajuste clave. Aunque la base muestre 64% de hoteles en Cuauhtemoc, tus datos externos pueden indicar que la proporción real es otra. Para este ejercicio definimos:

  • Hoteles en Cuauhtemoc: 50%.
  • Museos en Cuauhtémoc: 20%.
  • Hoteles en Venustiano Carranza: 10%.
  • Mercados en Cuauhtemoc: 10%.
  • Mercados en Venustiano Carranza: 10%.

La suma debe dar siempre 100%. Si te equivocas en un decimal, la función fallará o devolverá un tamaño de muestra incorrecto [03:30].

¿Cómo construir la función de muestreo estratificado?

El núcleo del proceso es una función que itera sobre cada estrato, calcula cuántas filas le corresponden y extrae la muestra aleatoria respetando ese tamaño.

python def data_estratificada(econdata, strat_columnas, strat_valores, strat_proporcion, random_state=None): df_estratificado = pd.DataFrame(columns=econdata.columns) pos = -1 for i in range(len(strat_valores)): if pos == len(strat_valores) - 1: ratio_length = len(econdata) - len(df_estratificado) else: ratio_length = int(len(econdata) * strat_proporcion[i]) df_filtrado = econdata[econdata[strat_columnas] == strat_valores[i]] df_temp = df_filtrado.sample(replace=True, n=ratio_length, random_state=random_state) df_estratificado = pd.concat([df_estratificado, df_temp]) return df_estratificado

La lógica detrás es la siguiente: si estás en la última iteración, la función calcula las filas restantes para que el total cuadre exactamente con el tamaño original. En las iteraciones previas, multiplica la longitud total por la proporción deseada y convierte el resultado a entero con int() [05:40].

¿Para qué sirve pd.concat en este flujo? Une cada submuestra estratificada en un solo DataFrame final. Sin esta concatenación tendrías fragmentos sueltos y no una muestra unificada.

¿Cómo invocas la función con tus valores reales?

Una vez definida la función, le pasas los argumentos: la base, la columna estratificada, la lista de valores únicos y la proporción deseada.

python strat_valores = ['Cuauhtemoc,Hotel', 'Cuauhtémoc,Museo', 'Venustiano Carranza,Hotel', 'Cuauhtemoc,Mercado', 'Venustiano Carranza,Mercado'] strat_proporcion = [0.5, 0.2, 0.1, 0.1, 0.1]

df_estratificado = data_estratificada(econdata, 'estratificado', strat_valores, strat_proporcion, random_state=42)

El parámetro random_state=42 te permite reproducir exactamente la misma muestra cada vez que corras el código. Si lo omites, cada ejecución generará una muestra diferente.

¿Por qué falla el código por un espacio extra?

Al ejecutar la función por primera vez puede aparecer un error que no es de lógica, sino de formato. Cuando creas la columna estratificada con delegacion + ',' + tipo, los valores quedan unidos sin espacio: Cuauhtemoc,Hotel.

Si al definir strat_valores escribes 'Cuauhtemoc, Hotel' con espacio después de la coma, Python no encontrará coincidencias y devolverá un DataFrame vacío o un error en sample. La solución es que el separador en la concatenación y en la lista de valores sea idéntico carácter por carácter [09:40].

¿Cómo evitas errores de coincidencia en strings de pandas? Asegúrate de que la cadena que generas al concatenar columnas tenga exactamente el mismo formato (espacios, tildes, mayúsculas) que la cadena con la que filtras después.

¿Qué resultado entrega el muestreo estratificado bien ejecutado?

Después de corregir el espacio, la función devuelve una muestra con 42 valores distribuidos según las proporciones que definiste: 50% hoteles en Cuauhtemoc, 20% museos, y tres bloques de 10% para los estratos restantes.

Las filas seleccionadas aparecen con índices salteados (142, 27, 168, etc.) porque el muestreo dentro de cada estrato sigue siendo aleatorio. Lo que cambia respecto a un muestreo aleatorio simple es que ahora cada subgrupo tiene representación garantizada en la proporción que tú decidiste.

No necesitas memorizar la función línea por línea. Lo importante es que entiendas la estructura: variable de estratificación, definición de proporciones, función con iteración condicional y concatenación final. Con esa lógica puedes adaptarla a cualquier dataset.

Practica con otras fuentes del gobierno de México y comparte en los comentarios cómo te fue con el muestreo estratificado, sistemático y aleatorio simple.