Finestre mobili
Calcoli medie, somme e deviazioni standard mobili su un numero fisso di righe con rolling(n).mean() e metodi correlati.
Finestre mobili è una lezione Pandas & NumPy Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Pandas & NumPy Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Cosa sono le finestre rolling?
Una finestra rolling (chiamata anche finestra scorrevole o mobile) calcola una statistica su una finestra di dimensione fissa composta da righe consecutive, facendola avanzare di una riga alla volta. Ad esempio, una media rolling su 7 giorni sostituisce il valore di ogni giorno con la media di quel giorno e dei 6 giorni precedenti. Le finestre rolling sono alla base delle medie mobili in ambito finanziario, del livellamento dei dati rumorosi dei sensori e del calcolo delle metriche retrospettive nei dashboard aziendali.
import pandas as pd
import numpy as np
# Simple example: 3-day rolling mean
data = pd.Series([10, 12, 15, 11, 9, 13, 16, 14, 12, 18],
index=pd.date_range('2024-01-01', periods=10))
rolling_mean = data.rolling(window=3).mean()
print('Original:')
print(data.values)
print('\n3-day rolling mean:')
print(rolling_mean.values.round(2))Il metodo rolling() e il parametro window
Series.rolling(window=n) restituisce un oggetto Rolling. Il parametro window indica la dimensione della finestra scorrevole in numero di righe (per le finestre intere) oppure come offset temporale, ad esempio '7D' (per le Series indicizzate temporalmente). Dopo aver creato l’oggetto rolling, concateni qualsiasi metodo di aggregazione: .mean(), .sum(), .std(), .min(), .max() o anche .apply(func). Le prime window-1 righe saranno sempre NaN perché non sono disponibili abbastanza righe precedenti per riempire la finestra.
import pandas as pd
import numpy as np
prices = pd.Series(
[100, 102, 98, 105, 110, 108, 115, 112, 120, 118],
index=pd.date_range('2024-01-01', periods=10),
name='price'
)
df = pd.DataFrame({'price': prices})
df['MA3'] = df['price'].rolling(3).mean()
df['MA7'] = df['price'].rolling(7).mean()
df['std3'] = df['price'].rolling(3).std()
print(df.round(2))Parametro min_periods
Per impostazione predefinita, rolling(n) richiede esattamente n valori non-NaN nella finestra prima di calcolare un risultato. Il parametro min_periods riduce questo requisito: ad esempio, rolling(7, min_periods=3) calcola la media non appena sono disponibili almeno 3 valori, producendo valori non-NaN prima nella Series. È utile quando desidera ottenere medie mobili anche all’inizio di una serie temporale, invece di NaN per le prime n-1 righe.
import pandas as pd
import numpy as np
prices = pd.Series([100, 102, 98, 105, 110, 108, 115],
index=pd.date_range('2024-01-01', periods=7))
# Default: first 6 rows are NaN
ma7_default = prices.rolling(7).mean()
# min_periods=3: compute mean once 3 values available
ma7_minperiods = prices.rolling(7, min_periods=3).mean()
df = pd.DataFrame({
'price': prices,
'MA7_default': ma7_default,
'MA7_min3': ma7_minperiods
})
print(df.round(2))Somma rolling per i totali progressivi
rolling(n).sum() calcola il totale delle ultime n righe in ogni posizione. Una somma rolling su 30 giorni delle vendite giornaliere fornisce il ricavo mensile retrospettivo per ogni giorno: è più informativa di un totale mensile statico perché si aggiorna quotidianamente. Le somme rolling sono comunemente utilizzate nell’analisi della vendita al dettaglio (vendite degli ultimi 30 giorni), nell’analisi web (utenti attivi degli ultimi 7 giorni) e nella finanza (volume degli ultimi n periodi).
import pandas as pd
import numpy as np
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=60)
daily_sales = pd.Series(np.random.randint(100, 500, 60), index=dates, name='daily_sales')
df = pd.DataFrame({'daily_sales': daily_sales})
df['trailing_7d'] = df['daily_sales'].rolling(7).sum()
df['trailing_30d'] = df['daily_sales'].rolling(30).sum()
print(df.tail(10).round(0))Deviazione standard rolling per la volatilità
In ambito finanziario, la volatilità viene misurata come deviazione standard rolling dei rendimenti giornalieri. Un’elevata std rolling indica forti oscillazioni dei prezzi; una std rolling bassa indica prezzi stabili. Questa metrica alimenta i calcoli del rischio nella valutazione delle opzioni e nella gestione dei portafogli. La formula è: calcoli i rendimenti logaritmici giornalieri con np.log(price/price.shift(1)), quindi applichi rolling(window).std().
import pandas as pd
import numpy as np
np.random.seed(0)
prices = pd.Series(
100 * np.exp(np.cumsum(np.random.normal(0.001, 0.02, 120))),
index=pd.date_range('2024-01-01', periods=120)
)
# Daily log returns
log_returns = np.log(prices / prices.shift(1))
# 20-day rolling volatility (annualised)
volatility = log_returns.rolling(20).std() * np.sqrt(252)
print('Last 5 rows of daily volatility:')
print(volatility.tail(5).round(4))Finestre rolling basate sul tempo
Invece di un numero fisso di righe, può specificare un offset temporale come finestra: rolling('7D') significa «gli ultimi 7 giorni di calendario dei dati». Questo gestisce correttamente le serie temporali non uniformi (fine settimana o festività mancanti): una finestra basata sul numero di righe includerebbe una quantità diversa di tempo di calendario a seconda delle lacune, mentre una finestra basata su un offset temporale copre sempre esattamente 7 giorni di dati. La Series deve avere un DatetimeIndex per utilizzare finestre basate sul tempo.
import pandas as pd
import numpy as np
# Business-day index (no weekends)
biz_dates = pd.bdate_range('2024-01-01', periods=15)
sales = pd.Series(np.random.randint(100, 300, 15), index=biz_dates)
# 7-calendar-day window (variable row count near weekends)
df = pd.DataFrame({'sales': sales})
df['rolling_7d'] = sales.rolling('7D').mean()
print(df.round(1))rolling apply per funzioni personalizzate
rolling(n).apply(func) passa ogni finestra alla funzione personalizzata come array NumPy. In questo modo può eseguire qualsiasi calcolo rolling non coperto dalle aggregazioni integrate, ad esempio la deviazione mediana assoluta rolling, l’asimmetria rolling o il primo quartile rolling. La funzione deve accettare un array 1-D e restituire uno scalare. Nota: apply è più lento dei metodi integrati perché non può essere vettorializzato.
import pandas as pd
import numpy as np
prices = pd.Series(
[100, 102, 98, 105, 110, 95, 115, 112, 120, 108],
index=pd.date_range('2024-01-01', periods=10)
)
# Rolling range (max - min) over a 5-day window
def rolling_range(arr):
return arr.max() - arr.min()
df = pd.DataFrame({'price': prices})
df['5d_range'] = prices.rolling(5).apply(rolling_range, raw=True)
print(df.round(2))Rolling sulle colonne di un DataFrame
Può applicare direttamente rolling().mean() a un DataFrame per calcolare statistiche rolling simultaneamente per tutte le colonne numeriche. Ogni colonna riceve una propria finestra rolling, calcolata indipendentemente. È utile per calcolare le medie mobili di più prezzi azionari o di più linee di vendita di prodotti in un’unica operazione, senza iterare sulle colonne.
import pandas as pd
import numpy as np
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10)
df = pd.DataFrame({
'AAPL': 100 + np.cumsum(np.random.randn(10)),
'MSFT': 200 + np.cumsum(np.random.randn(10)),
'GOOG': 150 + np.cumsum(np.random.randn(10))
}, index=dates)
# 3-day moving average of all three stocks
ma3 = df.rolling(3).mean()
print('3-day MA for all stocks:')
print(ma3.round(2))Combinare la media rolling con i dati originali
Un modello comune di visualizzazione consiste nel tracciare sugli stessi assi sia la serie temporale grezza sia la relativa media rolling. La media rolling evidenzia la tendenza attenuando il rumore quotidiano, mentre la serie grezza mostra la volatilità. La distanza tra le due indica la quantità di rumore presente. Aggiungere una media rolling a un DataFrame è semplice quanto assegnare il risultato a una nuova colonna.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=60)
sales = pd.Series(
200 + np.cumsum(np.random.randn(60) * 10),
index=dates, name='Daily Sales'
)
df = pd.DataFrame({'sales': sales})
df['MA7'] = df['sales'].rolling(7).mean()
df['MA30'] = df['sales'].rolling(30).mean()
df.plot(figsize=(12, 5), title='Sales with 7-day and 30-day Moving Average')
plt.ylabel('Sales')
plt.show()Finestre rolling centrate
Per impostazione predefinita, rolling utilizza una finestra retrospettiva (la riga corrente e le n-1 righe precedenti). Impostando center=True si crea una finestra centrata, in cui la riga corrente si trova al centro e vengono utilizzate in ugual numero righe passate e future. Le finestre centrate producono risultati più uniformi e sono adatte al livellamento offline di dati storici, quando i valori futuri sono noti. NON sono adatte alle previsioni in tempo reale perché richiedono dati futuri.
import pandas as pd
import numpy as np
np.random.seed(0)
data = pd.Series(
np.sin(np.linspace(0, 4*3.14159, 30)) + np.random.normal(0, 0.3, 30)
)
df = pd.DataFrame({'signal': data})
df['trailing_MA5'] = data.rolling(5).mean()
df['centered_MA5'] = data.rolling(5, center=True).mean()
print('Comparison (first 8 rows):')
print(df.head(8).round(3))Finestre mobili per dati raggruppati con GroupBy
È possibile calcolare statistiche mobili per gruppo usando groupby().rolling(). Ad esempio, per calcolare i ricavi mobili su 7 giorni per categoria di prodotto, la finestra viene reimpostata all'inizio di ogni gruppo, evitando che i dati di un prodotto confluiscano in quelli di un altro. Dopo l'operazione mobile, usi .reset_index(level=0, drop=True) per rimuovere dall'indice il livello aggiuntivo del gruppo e riallineare il risultato al DataFrame originale.
import pandas as pd
import numpy as np
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=10)
df = pd.DataFrame({
'date': list(dates) * 2,
'product': ['A'] * 10 + ['B'] * 10,
'sales': np.random.randint(50, 200, 20)
}).sort_values(['product', 'date'])
# 3-day rolling mean per product
df['rolling_mean'] = (df
.groupby('product')['sales']
.transform(lambda x: x.rolling(3).mean())
)
print(df.to_string(index=False))Verifica rapida
Verifichi la Sua comprensione delle finestre mobili illustrate in questa lezione.
Riepilogo della lezione
In questa lezione ha imparato che rolling(n) crea una finestra scorrevole di n righe su cui è possibile calcolare media, somma, deviazione standard, minimo, massimo o funzioni personalizzate, min_periods riduce il numero minimo di valori necessari per calcolare un risultato e center=True crea finestre centrate per lo smoothing offline. Ora esamineremo le finestre espandibili, ovvero statistiche cumulative che crescono dall'inizio della Series.
Domande Frequenti
La lezione «Finestre mobili» è gratuita?
Sì — il testo completo di «Finestre mobili» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Pandas & NumPy Academy, passa a CoddyKit PRO. Il corso Pandas & NumPy Academy include 4 lezioni in totale.
Cosa imparerò in «Finestre mobili»?
Calcoli medie, somme e deviazioni standard mobili su un numero fisso di righe con rolling(n).mean() e metodi correlati. Eserciti Pandas & NumPy Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Pandas & NumPy Academy?
Non è richiesta alcuna esperienza precedente. Pandas & NumPy Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.
Quanto tempo richiede la lezione «Finestre mobili»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Pandas & NumPy Academy?
Sì. Ogni lezione Pandas & NumPy Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Finestre mobili
- Finestre espandibili
- Media mobile ponderata esponenzialmente
- Ranghi e percentili all'interno dei gruppi