Percentiles en Python con NumPy
Aprende a calcular percentiles en Python con NumPy. Cubre cuartiles, detección de valores atípicos con IQR, métodos de interpolación y casos de uso en ML.
Un percentil indica el valor por debajo del cual cae un porcentaje determinado de las observaciones de tu conjunto de datos. Si un estudiante obtiene el percentil 80 en un examen, el 80 % de las puntuaciones están por debajo de la suya. Los percentiles son un pilar del análisis exploratorio de datos y se utilizan en machine learning para la detección de valores atípicos, el recorte de características y la generación de informes sobre el rendimiento del modelo en diferentes subgrupos.
Este capítulo abarca:
- Qué es un percentil y cómo se calcula
- Cómo usar
numpy.percentile()ynumpy.quantile() - Cuartiles y el resumen de cinco números
- El rango intercuartílico (IQR) para la detección de valores atípicos
- Métodos de interpolación y cuándo importan
- Cómo obtener el rango percentil de un valor específico con SciPy
- Casos de uso prácticos en ML: winsorización y recorte de datos
¿Qué es un percentil?
Un percentil divide un conjunto de datos ordenado en 100 partes iguales. El percentil P es el valor en o por debajo del cual cae el P por ciento de los datos.
| Percentil | Nombre común | Significado |
|---|---|---|
| 25 | Q1 (primer cuartil) | El 25 % de los valores están por debajo de este punto |
| 50 | Q2 / Mediana | La mitad de los valores están por debajo de este punto |
| 75 | Q3 (tercer cuartil) | El 75 % de los valores están por debajo de este punto |
| 90 | — | El 90 % de los valores están por debajo de este punto |
Los percentiles están estrechamente relacionados con la media, la mediana y la moda: el percentil 50 es exactamente la mediana.
Percentil vs. cuantil
Ambos términos se usan a menudo de manera intercambiable. Un cuantil expresa la misma idea usando una fracción de 0 a 1 en lugar de un porcentaje de 0 a 100:
- El percentil 25 = el cuantil 0,25
- El percentil 75 = el cuantil 0,75
NumPy ofrece tanto np.percentile() como np.quantile(). Se comportan de forma idéntica; elige el que haga tu código más claro.
Calcular un percentil con NumPy
numpy.percentile(a, q) recibe un array-like a y un percentil q (0–100) y devuelve el valor interpolado en esa posición.
Calcular el percentil 75 de un conjunto de datos
import numpy as np
data = [10, 20, 30, 40, 50]
result = np.percentile(data, 75)
print(result) # Output: 40.0Pasa una lista a q para calcular varios percentiles en una sola llamada — NumPy los devuelve en un array:
Calcular los percentiles 25, 50 y 75 a la vez
import numpy as np
data = [10, 20, 30, 40, 50]
p25, p50, p75 = np.percentile(data, [25, 50, 75])
print(f'Q1 = {p25}') # Output: Q1 = 20.0
print(f'Q2 = {p50}') # Output: Q2 = 30.0
print(f'Q3 = {p75}') # Output: Q3 = 40.0Usar np.quantile()
np.quantile() acepta una fracción (0,0–1,0) en lugar de un porcentaje:
Usar np.quantile() con un argumento de fracción
import numpy as np
data = [10, 20, 30, 40, 50]
q1 = np.quantile(data, 0.25)
q3 = np.quantile(data, 0.75)
print(f'Q1 = {q1}') # Output: Q1 = 20.0
print(f'Q3 = {q3}') # Output: Q3 = 40.0Cuartiles y el resumen de cinco números
Los tres cuartiles (Q1, Q2, Q3) junto con el mínimo y el máximo forman el resumen de cinco números — una instantánea compacta de la dispersión de cualquier conjunto de datos. Puedes calcular los cinco valores en una sola llamada:
Calcular el resumen de cinco números
import numpy as np
data = [10, 20, 30, 40, 50]
minimum, q1, median, q3, maximum = np.percentile(data, [0, 25, 50, 75, 100])
print(f'Min = {minimum}') # Output: Min = 10.0
print(f'Q1 = {q1}') # Output: Q1 = 20.0
print(f'Median = {median}') # Output: Median = 30.0
print(f'Q3 = {q3}') # Output: Q3 = 40.0
print(f'Max = {maximum}') # Output: Max = 50.0El resumen de cinco números es la base de un diagrama de caja (box plot), que puedes dibujar con Matplotlib (consulta Histogramas en Matplotlib para técnicas de visualización relacionadas).
El rango intercuartílico y la detección de valores atípicos
El rango intercuartílico (IQR) es la distancia entre Q1 y Q3:
IQR = Q3 − Q1Describe la dispersión del 50 % central de los datos. Como ignora los cuartos superior e inferior, el IQR es robusto frente a valores extremos, lo que lo convierte en la herramienta estándar para la detección de valores atípicos basada en reglas.
La regla del cercado de Tukey marca como posible valor atípico cualquier valor que supere 1,5 × IQR más allá de cualquiera de los cuartiles:
- Valla inferior: Q1 − 1,5 × IQR
- Valla superior: Q3 + 1,5 × IQR
Detectar valores atípicos con el método IQR
import numpy as np
data = [5, 7, 8, 9, 10, 11, 12, 13, 14, 80]
q1 = np.percentile(data, 25)
q3 = np.percentile(data, 75)
iqr = q3 - q1
lower_fence = q1 - 1.5 * iqr
upper_fence = q3 + 1.5 * iqr
outliers = [x for x in data if x < lower_fence or x > upper_fence]
print(f'Q1 = {q1}, Q3 = {q3}, IQR = {iqr}')
# Output: Q1 = 8.25, Q3 = 12.75, IQR = 4.5
print(f'Lower fence = {lower_fence}, Upper fence = {upper_fence}')
# Output: Lower fence = 1.5, Upper fence = 19.5
print(f'Outliers: {outliers}')
# Output: Outliers: [80]El valor 80 supera ampliamente la valla superior de 19,5, por lo que se marca como valor atípico. El método IQR es ampliamente utilizado porque no requiere ninguna suposición sobre la distribución de los datos subyacente.
Métodos de interpolación
Cuando el percentil solicitado cae entre dos puntos de datos, NumPy interpola. El parámetro method (añadido en NumPy 1.22, en sustitución del antiguo parámetro interpolation) controla cómo se realiza esta operación.
Comparar métodos de interpolación en el percentil 35
import numpy as np
data = [10, 20, 30, 40, 50]
# The 35th percentile falls between 20 (index 1) and 30 (index 2)
print(np.percentile(data, 35, method='linear')) # Output: 24.0 (default)
print(np.percentile(data, 35, method='lower')) # Output: 20
print(np.percentile(data, 35, method='higher')) # Output: 30
print(np.percentile(data, 35, method='midpoint')) # Output: 25.0
print(np.percentile(data, 35, method='nearest')) # Output: 20| Método | Descripción | Cuándo usarlo |
|---|---|---|
linear | Media ponderada de los dos valores adyacentes | Por defecto; estadísticamente más correcto |
lower | Devuelve el menor de los dos valores adyacentes | Cuando se requieren índices enteros |
higher | Devuelve el mayor de los dos valores adyacentes | Límites superiores conservadores |
midpoint | Media de lower y higher | Informes simples de punto medio |
nearest | Punto de datos real más cercano | Cuando el resultado debe ser una observación real |
Para la mayoría de los trabajos de análisis de datos y ML, el método linear predeterminado es la opción correcta.
Obtener el rango percentil de un valor
A veces tienes la pregunta inversa: dado un valor, ¿en qué percentil se encuentra? Usa scipy.stats.percentileofscore():
Encontrar el rango percentil que ocupa un valor específico
from scipy import stats
data = [10, 20, 30, 40, 50]
rank = stats.percentileofscore(data, 30)
print(rank) # Output: 60.0
rank_of_25 = stats.percentileofscore(data, 25)
print(rank_of_25) # Output: 40.0Una puntuación de 30 está en el percentil 60, lo que significa que el 60 % de los valores de data son iguales o inferiores a 30.
Caso de uso práctico en ML: winsorización
La winsorización (también llamada clipping) limita los valores extremos al límite de un percentil elegido en lugar de eliminarlos. Esto conserva el número de filas mientras reduce la influencia de los valores atípicos en el entrenamiento del modelo.
Recortar valores atípicos al rango del percentil 10 al 90
import numpy as np
data = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
lower = np.percentile(data, 10)
upper = np.percentile(data, 90)
clipped = np.clip(data, lower, upper)
print(f'Lower bound (10th): {lower}') # Output: Lower bound (10th): 20.0
print(f'Upper bound (90th): {upper}') # Output: Upper bound (90th): 100.0
print('Clipped:', list(clipped))
# Output: Clipped: [20.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0, 100.0]Ambos valores extremos — 10 (por debajo del límite del percentil 10, que es 20) y 200 (por encima del límite del percentil 90, que es 100) — se recortan al valor de la valla. La winsorización es un paso de preprocesamiento habitual antes de entrenar modelos lineales o redes neuronales, especialmente con datos financieros o de sensores donde las lecturas extremas son frecuentes.
Para más información sobre los enfoques de escalado de características que complementan el recorte basado en percentiles, consulta el capítulo Scale.
Referencia rápida
| Tarea | Función | Ejemplo |
|---|---|---|
| Percentil individual | np.percentile(data, q) | np.percentile(data, 75) |
| Varios percentiles | np.percentile(data, [q1, q2, …]) | np.percentile(data, [25, 50, 75]) |
| Cuantil (escala 0–1) | np.quantile(data, q) | np.quantile(data, 0.75) |
| Resumen de cinco números | np.percentile(data, [0,25,50,75,100]) | — |
| IQR | Q3 − Q1 | np.percentile(data, 75) - np.percentile(data, 25) |
| Rango percentil de un valor | scipy.stats.percentileofscore(data, v) | — |
| Recortar a límites de percentil | np.clip(data, lower, upper) | np.clip(data, p10, p90) |
Temas relacionados
- Media, mediana y moda — medidas de tendencia central; el percentil 50 es la mediana.
- Desviación estándar — mide la dispersión alrededor de la media; complementa el IQR.
- Distribución de datos — comprende la asimetría y los valores atípicos antes de elegir estadísticas de resumen.
- Scale — técnicas de escalado de características para el preprocesamiento en ML.
- Tutorial de NumPy — habilidades fundamentales de NumPy utilizadas a lo largo de este capítulo.
Conclusión
Los percentiles clasifican los valores dentro de un conjunto de datos y revelan su forma de maneras que la media y la desviación estándar no pueden. Con numpy.percentile(), calcular Q1, Q2, Q3 y el IQR requiere una sola línea de Python. En machine learning, los percentiles aparecen en cada etapa: en el análisis exploratorio de datos para detectar valores atípicos, en el preprocesamiento para winsorizar valores extremos y en la evaluación para comprender la precisión del modelo a lo largo de la distribución de tus datos. Dominarlos te proporciona una herramienta fiable y sin suposiciones que funciona con cualquier conjunto de datos independientemente de su distribución.