Vai al contenuto principale

Medie mobili in pandas

Scopri come cogliere i trend e dare senso ai dati di serie temporali con l’aiuto di una media mobile o scorrevole.
Aggiornato 29 set 2026  · 8 min leggi

Scopri con l'IA

ChatGPTClaudePerplexity

Introduzione

La media mobile, detta anche media scorrevole o mobile, viene usata per analizzare dati di serie temporali calcolando le medie di diversi sottoinsiemi del dataset completo. Poiché comporta il calcolo della media del dataset nel tempo, è chiamata anche media mobile semplice (MM) o rolling mean.

Esistono vari modi per calcolare la media mobile; uno consiste nel prendere un sottoinsieme fisso da un’intera serie di numeri. La prima media mobile si calcola facendo la media del primo sottoinsieme fisso di numeri, poi il sottoinsieme viene modificato spostandosi in avanti al successivo sottoinsieme fisso (includendo il valore futuro nel sottogruppo ed escludendo il numero precedente dalla serie).

La media mobile si usa soprattutto con dati di serie temporali per catturare le fluttuazioni di breve periodo concentrandosi allo stesso tempo sui trend di lungo periodo.

Alcuni esempi di dati di serie temporali sono i prezzi azionari, i bollettini meteo, la qualità dell’aria, il prodotto interno lordo, l’occupazione, ecc.

In generale, la media mobile rende i dati più omogenei.

La media mobile è alla base di molti algoritmi; uno di questi è il modello ARIMA (Autoregressive Integrated Moving Average), che usa le medie mobili per fare previsioni sulle serie temporali.

Esistono diversi tipi di medie mobili:

  • Simple Moving Average (SMA): la Simple Moving Average (SMA) usa una finestra scorrevole per calcolare la media su un numero fissato di periodi temporali. È una media pesata in modo uniforme dei precedenti dati n.

    Per capire meglio la SMA, prendiamo come esempio una sequenza di valori n:

    sequence of n values

    l’allineamento della media mobile a pesi uguali per n punti dati sarà essenzialmente la media dei precedenti M punti dati, dove M è la dimensione della finestra scorrevole:

    simple moving average calculation 1

    Allo stesso modo, per calcolare i valori successivi della media mobile, si aggiunge un nuovo valore alla somma e si elimina il valore del periodo precedente; dato che hai già la media dei periodi precedenti, non è necessaria la somma completa ogni volta:

    simple moving average calculation 2
  • Cumulative Moving Average (CMA): A differenza della semplice media mobile, che elimina l’osservazione più vecchia quando ne viene aggiunta una nuova, la cumulative moving average considera tutte le osservazioni precedenti. La CMA non è una tecnica molto efficace per analizzare i trend e levigare i dati. Il motivo è che fa la media di tutti i dati precedenti fino al punto dati corrente, quindi una media pesata uniformemente della sequenza di n valori:
    sequence of n values 2
    fino al tempo corrente è data da:
    cumulative moving average 1
    Analogamente, per aggiornare la media cumulativa a ogni nuovo valore in arrivo si può usare la seguente formula:
    cumulative moving average 2
  • Exponential Moving Average (EMA): A differenza di SMA e CMA, la media mobile esponenziale attribuisce più peso ai prezzi recenti e, di conseguenza, può essere un modello migliore o catturare il movimento del trend in modo più rapido. La reattività dell’EMA è direttamente proporzionale all’andamento dei dati.

Poiché le EMA danno un peso maggiore ai dati recenti rispetto a quelli più vecchi, sono più sensibili alle ultime variazioni di prezzo rispetto alle SMA; questo rende i risultati delle EMA più tempestivi e quindi l’EMA è spesso preferita ad altre tecniche.

Basta teoria, giusto? Passiamo all’implementazione pratica della media mobile.

Implementare la media mobile su dati di serie temporali

Simple Moving Average (SMA)

Per prima cosa, creiamo dei dati fittizi di serie temporale e proviamo a implementare la SMA usando solo Python.

Supponiamo che ci sia una domanda per un prodotto osservata per 12 mesi (1 anno) e che tu debba trovare le medie mobili con finestre di 3 e 4 mesi.

Importa i moduli

import pandas as pd
import numpy as np
 
product = {'month' : [1,2,3,4,5,6,7,8,9,10,11,12],'demand':[290,260,288,300,310,303,329,340,316,330,308,310]}
df = pd.DataFrame(product)
df.head()
 

Esegui e modifica il codice da questo tutorial online

Esegui codice
  month demand
0 1 290
1 2 260
2 3 288
3 4 300
4 5 310

Calcoliamo la SMA con una finestra di 3: significa che prenderai in considerazione tre valori ogni volta per calcolare la media mobile e, per ogni nuovo valore, quello più vecchio verrà ignorato.

Per implementarlo, userai la funzione iloc di pandas: poiché ti serve la colonna demand, fisserai la posizione di quella nella funzione iloc, mentre la riga sarà una variabile i che itererai fino a raggiungere la fine del dataframe.

for i in range(0,df.shape[0]-2):
    df.loc[df.index[i+2],'SMA_3'] = np.round(((df.iloc[i,1]+ df.iloc[i+1,1] +df.iloc[i+2,1])/3),1)
  month demand SMA_3
0 1 290 NaN
1 2 260 NaN
2 3 288 279.3
3 4 300 282.7
4 5 310 299.3

Per un controllo rapido, usiamo anche la funzione integrata rolling di pandas e verifichiamo se coincide con la nostra media mobile semplice implementata in Python.

df['pandas_SMA_3'] = df.iloc[:,1].rolling(window=3).mean()
df.head()
  month demand SMA_3 pandas_SMA_3
0 1 290 NaN NaN
1 2 260 NaN NaN
2 3 288 279.3 279.333333
3 4 300 282.7 282.666667
4 5 310 299.3 299.333333

Ottimo: come puoi vedere, le medie mobili personalizzate e quelle di pandas coincidono esattamente, il che significa che la tua implementazione della SMA è corretta.

Calcoliamo anche rapidamente la media mobile semplice per una window_size di 4.

for i in range(0,df.shape[0]-3):
    df.loc[df.index[i+3],'SMA_4'] = np.round(((df.iloc[i,1]+ df.iloc[i+1,1] +df.iloc[i+2,1]+df.iloc[i+3,1])/4),1)
df.head()
  month demand SMA_3 pandas_SMA_3 SMA_4
0 1 290 NaN NaN NaN
1 2 260 NaN NaN NaN
2 3 288 279.3 279.333333 NaN
3 4 300 282.7 282.666667 284.5
4 5 310 299.3 299.333333 289.5
df['pandas_SMA_4'] = df.iloc[:,1].rolling(window=4).mean()
df.head()
  month demand SMA_3 pandas_SMA_3 SMA_4 pandas_SMA_4
0 1 290 NaN NaN NaN NaN
1 2 260 NaN NaN NaN NaN
2 3 288 279.3 279.333333 NaN NaN
3 4 300 282.7 282.666667 284.5 284.5
4 5 310 299.3 299.333333 289.5 289.5

Ora traccerai i dati delle medie mobili che hai calcolato.

import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=[15,10])
plt.grid(True)
plt.plot(df['demand'],label='data')
plt.plot(df['SMA_3'],label='SMA 3 Months')
plt.plot(df['SMA_4'],label='SMA 4 Months')
plt.legend(loc=2)
<matplotlib.legend.Legend at 0x11fe15080>
calculated moving averages line graph

Media mobile cumulativa

Direi che ora siamo pronti per passare a un dataset reale.

Per la media mobile cumulativa, usiamo un air quality dataset che puoi scaricare da questo link.

df = pd.read_csv("AirQualityUCI/AirQualityUCI.csv", sep = ";", decimal = ",")
df = df.iloc[ : , 0:14]
df.head()
  Date Time CO(GT) PT08.S1(CO) NMHC(GT) C6H6(GT) PT08.S2(NMHC) NOx(GT) PT08.S3(NOx) NO2(GT) PT08.S4(NO2) PT08.S5(O3) T RH
0 10/03/2004 18.00.00 2.6 1360.0 150.0 11.9 1046.0 166.0 1056.0 113.0 1692.0 1268.0 13.6 48.9
1 10/03/2004 19.00.00 2.0 1292.0 112.0 9.4 955.0 103.0 1174.0 92.0 1559.0 972.0 13.3 47.7
2 10/03/2004 20.00.00 2.2 1402.0 88.0 9.0 939.0 131.0 1140.0 114.0 1555.0 1074.0 11.9 54.0
3 10/03/2004 21.00.00 2.2 1376.0 80.0 9.2 948.0 172.0 1092.0 122.0 1584.0 1203.0 11.0 60.0
4 10/03/2004 22.00.00 1.6 1272.0 51.0 6.5 836.0 131.0 1205.0 116.0 1490.0 1110.0 11.2 59.6

Il preprocessing è uno step essenziale quando lavori con i dati. Per i dati numerici, uno dei passaggi più comuni è controllare la presenza di valori NaN (Null). Se ci sono valori NaN, puoi sostituirli con 0, con la media, con i valori precedenti o successivi, o persino eliminarli. Sebbene la sostituzione sia di solito preferibile alla rimozione, dato che in questo dataset i valori NULL sono pochi, eliminarli non comprometterà la continuità della serie.

df.isna().sum()
Date             114
Time             114
CO(GT)           114
PT08.S1(CO)      114
NMHC(GT)         114
C6H6(GT)         114
PT08.S2(NMHC)    114
NOx(GT)          114
PT08.S3(NOx)     114
NO2(GT)          114
PT08.S4(NO2)     114
PT08.S5(O3)      114
T                114
RH               114
dtype: int64

Dal risultato sopra puoi notare che ci sono circa 114 valori NaN in tutte le colonne; tuttavia, scoprirai che sono tutti alla fine della serie temporale, quindi rimuoviamoli velocemente.

df.dropna(inplace=True)
df.isna().sum()
Date             0
Time             0
CO(GT)           0
PT08.S1(CO)      0
NMHC(GT)         0
C6H6(GT)         0
PT08.S2(NMHC)    0
NOx(GT)          0
PT08.S3(NOx)     0
NO2(GT)          0
PT08.S4(NO2)     0
PT08.S5(O3)      0
T                0
RH               0
dtype: int64

Applicherai la media mobile cumulativa alla colonna Temperature (T), quindi separiamo rapidamente quella colonna dal resto dei dati.

df_T = pd.DataFrame(df.iloc[:,-2])
df_T.head()
  T
0 13.6
1 13.3
2 11.9
3 11.0
4 11.2

Ora userai il metodo expanding di pandas per trovare la media cumulativa dei dati sopra. Se ricordi dall’introduzione, a differenza della media mobile semplice, la media mobile cumulativa considera tutti i valori precedenti nel calcolo della media.

df_T['CMA_4'] = df_T.expanding(min_periods=4).mean()
df_T.head(10)
  T CMA_4
0 13.6 NaN
1 13.3 NaN
2 11.9 NaN
3 11.0 12.450000
4 11.2 12.200000
5 11.2 12.033333
6 11.3 11.928571
7 10.7 11.775000
8 10.7 11.655556
9 10.3 11.520000

I dati di serie temporale si tracciano rispetto al tempo, quindi uniamo le colonne di data e ora e convertiamole in un oggetto datetime. Per farlo userai il modulo datetime di Python (Fonte: Time Series Tutorial).

import datetime

df['DateTime'] = (df.Date) + ' ' + (df.Time)
df.DateTime = df.DateTime.apply(lambda x: datetime.datetime.strptime(x, '%d/%m/%Y %H.%M.%S'))

Modifichiamo l’indice del dataframe temperature con il datetime.

df_T.index = df.DateTime

Ora tracciamo la temperatura reale e la media mobile cumulativa rispetto al tempo.

plt.figure(figsize=[15,10])
plt.grid(True)
plt.plot(df_T['T'],label='temperature')
plt.plot(df_T['CMA_4'],label='CMA_4')
plt.legend(loc=2)
<matplotlib.legend.Legend at 0x1210a2d30>
time series data graph

Exponential Moving Average

df_T['EMA'] = df_T.iloc[:,0].ewm(span=40,adjust=False).mean()
df_T.head()
  T CMA_4 EMA
DateTime      
2004-03-10 18:00:00 13.6 NaN 13.600000
2004-03-10 19:00:00 13.3 NaN 13.585366
2004-03-10 20:00:00 11.9 NaN 13.503153
2004-03-10 21:00:00 11.0 12.45 13.381048
2004-03-10 22:00:00 11.2 12.20 13.274655
plt.figure(figsize=[15,10])
plt.grid(True)
plt.plot(df_T['T'],label='temperature')
plt.plot(df_T['CMA_4'],label='CMA_4')
plt.plot(df_T['EMA'],label='EMA')
plt.legend(loc=2)
<matplotlib.legend.Legend at 0x14b2a41d0>
time series data graph 2

Wow! Come puoi osservare dal grafico sopra, la Exponential Moving Average (EMA) fa un ottimo lavoro nel catturare il pattern dei dati, mentre la Cumulative Moving Average (CMA) resta indietro in misura considerevole.

Vai oltre!

Congratulazioni per aver completato il tutorial.

Questo tutorial è stato un buon punto di partenza per capire come calcolare le medie mobili dei tuoi dati e dar loro un senso.

Prova a scrivere il codice Python per la media mobile cumulativa ed esponenziale senza usare la libreria pandas. Ti darà una comprensione più profonda di come vengono calcolate e in che modo differiscono tra loro.

C’è ancora molto da sperimentare. Prova a calcolare la correlazione parziale tra i dati in ingresso e la media mobile, e cerca di trovare qualche relazione tra i due.

Se vuoi saperne di più sui DataFrame in pandas, segui il corso interattivo pandas Foundations di DataCamp.

Riferimenti:

Per qualsiasi domanda su questo tutorial, scrivi pure nei commenti qui sotto.

Argomenti
Python
Data Visualization
Analisi dei dati

Corsi correlati

{count, plural, one {Corso} other {Corsi}}

Python - Livello Intermedio

{hours} ore
1.4M
Migliora le tue competenze nella scienza dei dati creando visualizzazioni con Matplotlib e manipolando DataFrames con pandas.
Vedi i dettagliRight Arrow
Inizia Il Corso
Mostra altroRight Arrow
Correlato

{count, plural, one {blog} other {blogs}}

I 15 migliori server MCP remoti che ogni AI builder dovrebbe conoscere nel 2026

Scopri i 15 migliori server MCP remoti che stanno trasformando lo sviluppo AI nel 2026. Scopri come migliorano automazione, ragionamento, sicurezza e velocità dei workflow.
Abid Ali Awan's photo

Abid Ali Awan

15 min

{count, plural, one {blog} other {blogs}}

Che cos'è Snowflake? Guida per principianti alla piattaforma dati cloud

Esplora le basi di Snowflake, la piattaforma dati cloud. Scopri la sua architettura, le sue funzionalità e come integrarla nelle tue pipeline di dati.
Tim Lu's photo

Tim Lu

12 min

{count, plural, one {blog} other {blogs}}

Tokenizzazione nel NLP: come funziona, sfide e casi d'uso

Guida al preprocessing NLP nel machine learning. Copriamo spaCy, i transformer di Hugging Face e come funziona la tokenizzazione in casi d'uso reali.
Abid Ali Awan's photo

Abid Ali Awan

10 min

Mostra AltroMostra Altro