Percentis em Python com NumPy
Aprenda a calcular percentis em Python com NumPy. Abrange quartis, detecção de outliers com IQR, métodos de interpolação e casos de uso em ML.
Um percentil indica o valor abaixo do qual uma determinada porcentagem de observações do conjunto de dados se encontra. Se um aluno está no 80º percentil em uma prova, 80% das notas estão abaixo da dele. Os percentis são um pilar da análise exploratória de dados e são usados em machine learning para detecção de outliers, recorte de features e relatórios de desempenho de modelos em subgrupos.
Este capítulo aborda:
- O que é um percentil e como ele é calculado
- Como usar
numpy.percentile()enumpy.quantile() - Quartis e o resumo dos cinco números
- O intervalo interquartil (IQR) para detecção de outliers
- Métodos de interpolação e quando eles importam
- Como encontrar a posição percentil de um valor específico com SciPy
- Casos práticos em ML: winsorização e recorte de dados
O que é um Percentil?
Um percentil divide um conjunto de dados ordenado em 100 partes iguais. O P-ésimo percentil é o valor em que ou abaixo do qual P por cento dos dados se encontram.
| Percentil | Nome comum | Significado |
|---|---|---|
| 25º | Q1 (primeiro quartil) | 25% dos valores estão abaixo deste ponto |
| 50º | Q2 / Mediana | Metade dos valores está abaixo deste ponto |
| 75º | Q3 (terceiro quartil) | 75% dos valores estão abaixo deste ponto |
| 90º | — | 90% dos valores estão abaixo deste ponto |
Os percentis estão intimamente relacionados com média, mediana e moda: o 50º percentil é exatamente a mediana.
Percentil vs. quantil
Os termos são frequentemente usados de forma intercambiável. Um quantil expressa a mesma ideia usando uma fração de 0 a 1 em vez de uma porcentagem de 0 a 100:
- O 25º percentil = o quantil 0,25
- O 75º percentil = o quantil 0,75
O NumPy fornece tanto np.percentile() quanto np.quantile(). Eles se comportam de forma idêntica; escolha aquele que tornar o seu código mais claro.
Calculando um Percentil com NumPy
numpy.percentile(a, q) recebe um array-like a e um percentil q (0–100) e retorna o valor interpolado nessa posição.
Calcular o 75º percentil de um conjunto de dados
import numpy as np
data = [10, 20, 30, 40, 50]
result = np.percentile(data, 75)
print(result) # Output: 40.0Passe uma lista para q para calcular múltiplos percentis em uma única chamada — o NumPy os retorna em um array:
Calcular o 25º, 50º e 75º percentis de uma 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.0Usando np.quantile()
np.quantile() aceita uma fração (0,0–1,0) em vez de uma porcentagem:
Usar np.quantile() com um argumento de fração
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.0Quartis e o Resumo dos Cinco Números
Os três quartis (Q1, Q2, Q3) junto com o mínimo e o máximo formam o resumo dos cinco números — um instantâneo compacto da distribuição de qualquer conjunto de dados. É possível calcular todos os cinco valores em uma única chamada:
Calcular o resumo dos 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.0O resumo dos cinco números é a base de um box plot, que pode ser desenhado com Matplotlib (veja Histogramas com Matplotlib para técnicas de visualização relacionadas).
O Intervalo Interquartil e a Detecção de Outliers
O intervalo interquartil (IQR) é a distância entre Q1 e Q3:
IQR = Q3 − Q1Ele descreve a dispersão dos 50% centrais dos dados. Por ignorar os quartos superior e inferior, o IQR é robusto a valores extremos — tornando-se a ferramenta padrão para detecção de outliers baseada em regras.
A regra da cerca de Tukey sinaliza qualquer valor que ultrapasse mais de 1,5 × IQR além de qualquer quartil como um possível outlier:
- Cerca inferior: Q1 − 1,5 × IQR
- Cerca superior: Q3 + 1,5 × IQR
Detectar outliers usando o 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]O valor 80 está bem além da cerca superior de 19,5, portanto é sinalizado como outlier. O método IQR é amplamente usado porque não exige suposições sobre a distribuição dos dados subjacente.
Métodos de Interpolação
Quando o percentil solicitado cai entre dois pontos de dados, o NumPy interpola. O parâmetro method (adicionado no NumPy 1.22, substituindo o parâmetro mais antigo interpolation) controla como isso é feito.
Comparar métodos de interpolação no 35º percentil
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 | Descrição | Quando usar |
|---|---|---|
linear | Média ponderada dos dois valores vizinhos | Padrão; mais correto estatisticamente |
lower | Retorna o menor dos dois valores vizinhos | Quando índices inteiros são necessários |
higher | Retorna o maior dos dois valores vizinhos | Limites superiores conservadores |
midpoint | Média do inferior e do superior | Relatórios simples de ponto médio |
nearest | Ponto de dados real mais próximo | Quando o resultado deve ser uma observação real |
Para a maioria dos trabalhos de análise de dados e ML, o método padrão linear é a escolha certa.
Encontrando a Posição Percentil de um Valor
Às vezes a questão é inversa: dado um valor, em qual percentil ele se encontra? Use scipy.stats.percentileofscore():
Descobrir qual posição percentil um valor específico ocupa
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.0Uma pontuação de 30 está no 60º percentil — o que significa que 60% dos valores em data são iguais ou inferiores a 30.
Caso Prático em ML: Winsorização
A winsorização (também chamada de clipping) limita valores extremos ao limite de um percentil escolhido, em vez de removê-los. Isso preserva o número de linhas enquanto limita a influência de outliers no treinamento do modelo.
Recortar outliers para o intervalo do 10º ao 90º percentil
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 os valores extremos — 10 (abaixo do limite do 10º percentil de 20) e 200 (acima do limite do 90º percentil de 100) — são limitados ao valor da cerca. A winsorização é uma etapa de pré-processamento comum antes do treinamento de modelos lineares ou redes neurais, especialmente em dados financeiros ou de sensores onde leituras extremas são frequentes.
Para mais informações sobre abordagens de escalonamento de features que complementam o recorte baseado em percentis, consulte o capítulo Scale.
Referência Rápida
| Tarefa | Função | Exemplo |
|---|---|---|
| Percentil único | np.percentile(data, q) | np.percentile(data, 75) |
| Múltiplos percentis | np.percentile(data, [q1, q2, …]) | np.percentile(data, [25, 50, 75]) |
| Quantil (escala 0–1) | np.quantile(data, q) | np.quantile(data, 0.75) |
| Resumo dos cinco números | np.percentile(data, [0,25,50,75,100]) | — |
| IQR | Q3 − Q1 | np.percentile(data, 75) - np.percentile(data, 25) |
| Posição percentil de um valor | scipy.stats.percentileofscore(data, v) | — |
| Recortar até os limites do percentil | np.clip(data, lower, upper) | np.clip(data, p10, p90) |
Tópicos Relacionados
- Média, Mediana e Moda — medidas de tendência central; o 50º percentil é a mediana.
- Desvio Padrão — mede a dispersão em torno da média; complementa o IQR.
- Distribuição de Dados — compreenda a assimetria e os outliers antes de escolher estatísticas resumidas.
- Scale — técnicas de escalonamento de features para pré-processamento em ML.
- Tutorial NumPy — habilidades fundamentais de NumPy usadas ao longo deste capítulo.
Conclusão
Os percentis classificam valores dentro de um conjunto de dados e revelam sua forma de maneiras que a média e o desvio padrão não conseguem. Com numpy.percentile(), calcular Q1, Q2, Q3 e o IQR exige apenas uma linha de Python. Em machine learning, os percentis aparecem em todas as etapas: na análise exploratória de dados para identificar outliers, no pré-processamento para winsorizar valores extremos e na avaliação para entender a precisão do modelo ao longo da distribuição dos dados. Dominá-los oferece uma ferramenta confiável e sem suposições que funciona em qualquer conjunto de dados, independentemente de sua distribuição.