Pandas & NumPy Academy · Aula

Janelas móveis

Calcule médias, somas e desvios-padrão móveis sobre um número fixo de linhas com rolling(n).mean() e métodos relacionados.

Aula 1 de 413 etapas

Janelas móveis é uma aula grátis de Pandas & NumPy Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Pandas & NumPy Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Pandas & NumPy Academy inclui 4 aulas no total.

O que são janelas móveis

Uma janela móvel (também chamada de janela deslizante) calcula uma estatística sobre uma janela de tamanho fixo composta por linhas consecutivas, à medida que avança uma linha por vez. Por exemplo, uma média móvel de 7 dias substitui o valor de cada dia pela média desse dia e dos 6 dias anteriores. As janelas móveis são a base das médias móveis em finanças, da suavização de dados ruidosos de sensores e do cálculo de métricas acumuladas em painéis de negócios.

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))

O método rolling() e o parâmetro window

Series.rolling(window=n) retorna um objeto Rolling. O parâmetro window define o tamanho da janela deslizante em número de linhas (para janelas inteiras) ou como um deslocamento temporal, como '7D' (para Series indexadas por tempo). Depois de criar o objeto móvel, encadeie qualquer método de agregação: .mean(), .sum(), .std(), .min(), .max() ou até mesmo .apply(func). As primeiras window-1 linhas sempre serão NaN, pois não há linhas anteriores suficientes para preencher a janela.

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))

Parâmetro min_periods

Por padrão, rolling(n) exige exatamente n valores não NaN na janela antes de calcular um resultado. O parâmetro min_periods reduz essa exigência — por exemplo, rolling(7, min_periods=3) calcula a média assim que pelo menos 3 valores estão disponíveis, produzindo valores não NaN mais cedo na Series. Isso é útil quando você deseja médias móveis no início de uma série temporal, em vez de NaN nas primeiras n-1 linhas.

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))

Soma móvel para totais acumulados

rolling(n).sum() calcula o total das últimas n linhas em cada posição. Uma soma móvel de 30 dias das vendas diárias fornece a receita mensal acumulada de cada dia — mais informativa do que um total mensal estático, pois é atualizada diariamente. Som as móveis são usadas com frequência em análises de varejo (vendas dos últimos 30 dias), análises da web (usuários ativos nos últimos 7 dias) e finanças (volume acumulado dos últimos n períodos).

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))

Desvio padrão móvel para medir a volatilidade

Em finanças, a volatilidade é medida como o desvio padrão móvel dos retornos diários. Um desvio padrão móvel alto significa que os preços estão oscilando intensamente; um desvio padrão móvel baixo indica preços estáveis. Essa métrica orienta cálculos de risco na precificação de opções e na gestão de carteiras. A fórmula é: calcule os retornos logarítmicos diários com np.log(price/price.shift(1)) e, em seguida, aplique 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))

Janelas móveis baseadas em tempo

Em vez de um número fixo de linhas, você pode especificar um deslocamento temporal como janela: rolling('7D') significa “os últimos 7 dias corridos de dados”. Isso lida automaticamente de forma correta com séries temporais irregulares (fins de semana e feriados ausentes) — uma janela baseada na quantidade de linhas incluiria uma quantidade diferente de tempo de calendário dependendo das lacunas, mas uma janela baseada em deslocamento temporal sempre abrangerá exatamente 7 dias de dados. A Series deve ter um DatetimeIndex para usar janelas baseadas em 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))

Apply móvel para funções personalizadas

rolling(n).apply(func) passa cada janela como um vetor NumPy para sua função personalizada. Isso permite realizar qualquer cálculo móvel que não seja coberto pelas agregações integradas — por exemplo, desvio absoluto mediano móvel, assimetria móvel ou primeiro quartil móvel. A função deve aceitar um vetor unidimensional e retornar um escalar. Observação: apply é mais lento do que os métodos integrados porque não pode ser vetorizado.

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))

Aplicando rolling às colunas de um DataFrame

Você pode aplicar rolling().mean() diretamente a um DataFrame para calcular estatísticas móveis de todas as colunas numéricas simultaneamente. Cada coluna recebe sua própria janela móvel, calculada de forma independente. Isso é útil para calcular médias móveis de vários preços de ações ou de várias linhas de vendas de produtos em uma única operação, sem percorrer as colunas.

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))

Combinando a média móvel com os dados originais

Um padrão comum de visualização é plotar a série temporal bruta e sua média móvel nos mesmos eixos. A média móvel revela a tendência ao suavizar o ruído diário, enquanto a série bruta mostra a volatilidade. A distância entre elas indica quanto ruído está presente. Adicionar uma média móvel a um DataFrame é tão simples quanto atribuir o resultado a uma nova coluna.

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()

Janelas móveis centralizadas

Por padrão, rolling usa uma janela acumulada (a linha atual e as n-1 linhas anteriores). Definir center=True cria uma janela centralizada, na qual a linha atual fica no meio, usando a mesma quantidade de linhas anteriores e posteriores. As janelas centralizadas produzem resultados mais suaves e são apropriadas para a suavização offline de dados históricos, quando os valores futuros são conhecidos. Elas NÃO são apropriadas para previsões em tempo real, pois exigem dados futuros.

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))

Janelas móveis para dados agrupados por GroupBy

Você pode calcular estatísticas móveis por grupo usando groupby().rolling(). Por exemplo, ao calcular a receita móvel de 7 dias por categoria de produto, a janela é reiniciada no início de cada grupo, portanto os dados de um produto não se misturam aos de outro. Após a operação móvel, use .reset_index(level=0, drop=True) para remover o nível extra do grupo do índice e alinhar o resultado novamente ao DataFrame original.

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ção rápida

Teste sua compreensão sobre janelas móveis nesta lição.

Resumo da lição

Nesta lição, você aprendeu que rolling(n) cria uma janela deslizante de n linhas na qual é possível calcular mean, sum, std, min, max ou funções personalizadas; min_periods reduz o número mínimo de valores necessários para calcular um resultado; e center=True cria janelas centralizadas para suavização offline. A seguir, exploraremos as janelas expansíveis — estatísticas cumulativas que crescem desde o início da Series.

Grátis para começar

Aprenda Python com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
30
Aulas
120

Perguntas Frequentes

A aula “Janelas móveis” é grátis?

Sim — o texto completo de “Janelas móveis” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Pandas & NumPy Academy, atualize para CoddyKit PRO. O curso de Pandas & NumPy Academy inclui 4 aulas no total.

O que vou aprender em “Janelas móveis”?

Calcule médias, somas e desvios-padrão móveis sobre um número fixo de linhas com rolling(n).mean() e métodos relacionados. Você pratica Pandas & NumPy Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Pandas & NumPy Academy?

Nenhuma experiência prévia é necessária. Pandas & NumPy Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Janelas móveis”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Pandas & NumPy Academy?

Sim. Cada aula de Pandas & NumPy Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Janelas móveis
  2. Janelas expansivas
  3. Média móvel ponderada exponencialmente
  4. Classificação e percentil dentro dos grupos
← Voltar para Pandas & NumPy Academy