W3docs

Percentili in Python con NumPy

Calcola i percentili in Python con NumPy. Quartili, IQR per rilevare outlier, metodi di interpolazione e casi d'uso pratici nel ML.

Un percentile indica il valore al di sotto del quale cade una determinata percentuale di osservazioni nel dataset. Se uno studente si colloca all'80° percentile in un esame, l'80 % dei punteggi è inferiore al suo. I percentili sono un pilastro dell'analisi esplorativa dei dati e vengono utilizzati nel machine learning per il rilevamento di outlier, il clipping delle feature e la reportistica delle prestazioni del modello tra i sottogruppi.

Questo capitolo tratta:

  • Cosa si intende per percentile e come viene calcolato
  • Come usare numpy.percentile() e numpy.quantile()
  • Quartili e il sommario a cinque numeri
  • L'intervallo interquartile (IQR) per il rilevamento degli outlier
  • Metodi di interpolazione e quando sono rilevanti
  • Trovare il rango percentile di un valore specifico con SciPy
  • Casi d'uso pratici nel ML: winsorizzazione e clipping dei dati

Cos'è un Percentile?

Un percentile divide un dataset ordinato in 100 parti uguali. Il P-esimo percentile è il valore al di sotto del quale (o uguale al quale) cade il P percento dei dati.

PercentileNome comuneSignificato
25°Q1 (primo quartile)Il 25 % dei valori è al di sotto di questo punto
50°Q2 / MedianaLa metà dei valori è al di sotto di questo punto
75°Q3 (terzo quartile)Il 75 % dei valori è al di sotto di questo punto
90°Il 90 % dei valori è al di sotto di questo punto

I percentili sono strettamente correlati a media, mediana e moda: il 50° percentile corrisponde esattamente alla mediana.

Percentile vs. quantile

I due termini sono spesso usati in modo intercambiabile. Un quantile esprime la stessa idea usando una frazione da 0 a 1 invece di una percentuale da 0 a 100:

  • Il 25° percentile = il quantile 0,25
  • Il 75° percentile = il quantile 0,75

NumPy fornisce sia np.percentile() che np.quantile(). Si comportano in modo identico; scegli quello che rende il tuo codice più chiaro.

Calcolare un Percentile con NumPy

numpy.percentile(a, q) accetta un array-like a e un percentile q (0–100) e restituisce il valore interpolato in quella posizione.

Calcola il 75° percentile di un dataset

import numpy as np

data = [10, 20, 30, 40, 50]
result = np.percentile(data, 75)
print(result)  # Output: 40.0

Passa una lista a q per calcolare più percentili in una sola chiamata — NumPy li restituisce in un array:

Calcola il 25°, 50° e 75° percentile in una volta sola

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.0

Usare np.quantile()

np.quantile() accetta una frazione (0,0–1,0) invece di una percentuale:

Usa np.quantile() con un argomento frazionario

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.0

Quartili e il Sommario a Cinque Numeri

I tre quartili (Q1, Q2, Q3) insieme al minimo e al massimo formano il sommario a cinque numeri — un'istantanea compatta della distribuzione di qualsiasi dataset. Puoi calcolare tutti e cinque i valori con una singola chiamata:

Calcola il sommario a cinque numeri

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.0

Il sommario a cinque numeri è la base di un box plot, che puoi disegnare con Matplotlib (vedi Istogrammi con Matplotlib per tecniche di visualizzazione correlate).

L'Intervallo Interquartile e il Rilevamento degli Outlier

L'intervallo interquartile (IQR) è la distanza tra Q1 e Q3:

IQR = Q3 − Q1

Descrive la dispersione del 50 % centrale dei dati. Poiché ignora il quarto superiore e quello inferiore, l'IQR è robusto ai valori estremi — rendendolo lo strumento standard per il rilevamento degli outlier basato su regole.

La regola del recinto di Tukey segnala come potenziale outlier qualsiasi valore che superi di oltre 1,5 × IQR i limiti di ciascun quartile:

  • Recinto inferiore: Q1 − 1,5 × IQR
  • Recinto superiore: Q3 + 1,5 × IQR

Rileva gli outlier usando il metodo 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]

Il valore 80 è ben oltre il recinto superiore di 19,5, quindi viene segnalato come outlier. Il metodo IQR è ampiamente utilizzato perché non richiede alcuna assunzione sulla distribuzione dei dati sottostante.

Metodi di Interpolazione

Quando il percentile richiesto cade tra due punti del dataset, NumPy interpola. Il parametro method (aggiunto in NumPy 1.22, in sostituzione del vecchio parametro interpolation) controlla come viene effettuata l'interpolazione.

Confronta i metodi di interpolazione al 35° percentile

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
MetodoDescrizioneQuando usarlo
linearMedia ponderata dei due valori circostantiPredefinito; statisticamente più corretto
lowerRestituisce il minore dei due valori circostantiQuando sono richiesti indici interi
higherRestituisce il maggiore dei due valori circostantiLimiti superiori conservativi
midpointMedia tra il valore inferiore e quello superioreReportistica semplice del punto medio
nearestIl punto dati effettivo più vicinoQuando il risultato deve essere un'osservazione reale

Per la maggior parte delle analisi dei dati e del lavoro ML, il metodo predefinito linear è la scelta giusta.

Trovare il Rango Percentile di un Valore

A volte si pone la domanda inversa: dato un valore, a quale percentile corrisponde? Usa scipy.stats.percentileofscore():

Trova il rango percentile occupato da un valore specifico

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.0

Un punteggio di 30 si trova al 60° percentile — il che significa che il 60 % dei valori in data è uguale o inferiore a 30.

Caso d'Uso Pratico nel ML: Winsorizzazione

La winsorizzazione (chiamata anche clipping) limita i valori estremi a un confine percentile scelto invece di rimuoverli. Questo conserva il numero di righe riducendo al contempo l'influenza degli outlier sull'addestramento del modello.

Taglia gli outlier all'intervallo dal 10° al 90° percentile

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]

Entrambi i valori estremi — 10 (al di sotto del limite del 10° percentile pari a 20) e 200 (al di sopra del limite del 90° percentile pari a 100) — vengono portati al valore del recinto. La winsorizzazione è una fase di preprocessing comune prima dell'addestramento di modelli lineari o reti neurali, specialmente su dati finanziari o di sensori dove i valori estremi sono frequenti.

Per ulteriori informazioni sugli approcci di scaling delle feature che si affiancano al clipping basato sui percentili, consulta il capitolo Scale.

Riferimento Rapido

OperazioneFunzioneEsempio
Percentile singolonp.percentile(data, q)np.percentile(data, 75)
Più percentilinp.percentile(data, [q1, q2, …])np.percentile(data, [25, 50, 75])
Quantile (scala 0–1)np.quantile(data, q)np.quantile(data, 0.75)
Sommario a cinque numerinp.percentile(data, [0,25,50,75,100])
IQRQ3 − Q1np.percentile(data, 75) - np.percentile(data, 25)
Rango percentile di un valorescipy.stats.percentileofscore(data, v)
Taglia ai limiti percentilenp.clip(data, lower, upper)np.clip(data, p10, p90)

Argomenti Correlati

  • Media, Mediana e Moda — misure di tendenza centrale; il 50° percentile è la mediana.
  • Deviazione Standard — misura la dispersione attorno alla media; complementa l'IQR.
  • Distribuzione dei Dati — comprendi asimmetria e outlier prima di scegliere le statistiche sommarie.
  • Scale — tecniche di scaling delle feature per il preprocessing nel ML.
  • Tutorial NumPy — competenze fondamentali di NumPy utilizzate in tutto questo capitolo.

Conclusione

I percentili classificano i valori all'interno di un dataset e ne rivelano la forma in modi che la media e la deviazione standard non possono. Con numpy.percentile(), il calcolo di Q1, Q2, Q3 e IQR richiede una singola riga di Python. Nel machine learning, i percentili compaiono in ogni fase: nell'analisi esplorativa dei dati per individuare gli outlier, nel preprocessing per winsorizzare i valori estremi e nella valutazione per comprendere l'accuratezza del modello sull'intera distribuzione dei dati. Padroneggiarlo ti fornisce uno strumento affidabile e privo di assunzioni che funziona su qualsiasi dataset indipendentemente dalla sua distribuzione.

Was this page helpful?