(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Como fazer pré-processamento de dados de séries temporais no Azure ML: passo a passo

João Barros 25 de September de 2026 4 min de leitura

Preparar séries temporais é muitas vezes a parte mais importante antes de treinar um modelo. Este tutorial mostra como fazer pré-processamento de dados de séries temporais no Azure AI & Machine Learning para ter dados limpos, imputados e com características temporais úteis para modelos de forecasting ou classificação.

Pré-requisitos

  • Conta Azure com subscrição ativa e permissões para criar recursos.
  • Workspace do Azure Machine Learning criado.
  • Familiaridade básica com Python e Jupyter Notebooks.
  • Python 3.8+ com pacotes: pandas, azureml-core, azureml-dataset-runtime.

Passo 1: Carregar os dados para o Workspace

Os dados podem estar num blob, Data Lake ou local. Aqui usamos um ficheiro CSV com colunas mínimas: timestamp e value. Vamos registar o ficheiro como um Dataset no Workspace para reprodutibilidade e governação de dados.

from azureml.core import Workspace, Dataset

ws = Workspace.from_config()
datastore = ws.get_default_datastore()
# carrega o ficheiro local para o datastore (uma única vez)
datastore.upload_files(files=['./series.csv'], target_path='series/', overwrite=True)

# regista como Dataset
ds = Dataset.Tabular.from_delimited_files(path=(datastore, 'series/series.csv'))
ds = ds.register(workspace=ws, name='series_raw', description='Série temporal bruta')

Passo 2: Exploração inicial e deteção de problemas

Explorar rapidamente para ver faltas, duplicados, formatos de data e irregularidades de frequência. Isto ajuda a decidir imputação e agregação.

import pandas as pd

df = ds.to_pandas_dataframe()
df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.sort_values('timestamp').reset_index(drop=True)
print(df.info())
print(df.head())
print('Missing values:', df['value'].isna().sum())

Passo 3: Normalizar timestamps e definir frequência

Converter para um índice DatetimeIndex e reindexar para uma frequência regular (por ex.: hourly, daily). Isso facilita a imputação e a criação de features de lag.

# definir índice e reindexar para frequência horária
freq = 'H'  # ajustar conforme a série
idx = pd.date_range(start=df['timestamp'].min(), end=df['timestamp'].max(), freq=freq)
df = df.set_index('timestamp').reindex(idx).rename_axis('timestamp').reset_index()

Passo 4: Imputação de valores em falta

Escolher método simples primeiro: forward-fill/backfill, interpolação linear ou média móvel. Para séries com sazonalidade, usar interpolação ou modelos mais avançados depois.

# exemplos de imputação
# forward-fill seguido de backfill para extremos
df['value_ffill'] = df['value'].fillna(method='ffill').fillna(method='bfill')

# interpolação linear
df['value_interp'] = df['value'].interpolate(method='time')

# média móvel (janela 3)
df['value_ma3'] = df['value'].fillna(df['value'].rolling(window=3, min_periods=1).mean())

Passo 5: Criar características temporais e lags

Características como hour, dayofweek, month e lags são essenciais para modelos. Criar lags e médias móveis para capturar dependências temporais.

# características temporais
df['hour'] = df['timestamp'].dt.hour
df['dayofweek'] = df['timestamp'].dt.dayofweek
df['month'] = df['timestamp'].dt.month

# lags e rolling
for lag in [1, 24, 168]:  # ex.: 1h, 1 dia, 1 semana (horária)
    df[f'lag_{lag}'] = df['value_interp'].shift(lag)

# rolling mean
df['rolling_24'] = df['value_interp'].shift(1).rolling(window=24, min_periods=1).mean()

# eliminar primeiras linhas com NaNs decorrentes de lags
df = df.dropna().reset_index(drop=True)

Passo 6: Dividir treino/validação e exportar Dataset

Dividir temporalmente (sem embaralhar). Registar o resultado como novo Dataset para treino e reprodutibilidade do pipeline.

train_end = int(len(df) * 0.8)
train_df = df.iloc[:train_end]
val_df = df.iloc[train_end:]

# exportar para CSV e subir para datastore
train_df.to_csv('train_prepared.csv', index=False)
val_df.to_csv('val_prepared.csv', index=False)

datastore.upload_files(files=['train_prepared.csv','val_prepared.csv'], target_path='series/prepared/', overwrite=True)

from azureml.core import Dataset
prepared_train = Dataset.Tabular.from_delimited_files(path=(datastore, 'series/prepared/train_prepared.csv'))
prepared_train = prepared_train.register(workspace=ws, name='series_train_prepared')

Verificar o resultado

Confirmar que não existem NaNs nas características usadas pelo modelo, verificar distribuição temporal e que os lags estão alinhados corretamente. Testes rápidos:

print('Train rows:', len(train_df))
print('Nulls por coluna:\n', train_df.isna().sum())
print('Timestamp sample:', train_df['timestamp'].iloc[:5])
# visualizar algumas características
print(train_df[['timestamp','value_interp','lag_1','rolling_24']].head())

Conclusão

Tem agora uma pipeline básica de pré-processamento de séries temporais no Azure AI & Machine Learning: carregou dados, imputou faltas, criou características temporais e lags e registou o Dataset preparado para treino. Próximos passos: experimentar técnicas de imputação avançada (ex.: Prophet, KNN imputation), engenharia de características sazonais e integrar este código como um Pipeline no Azure ML. Dica: sempre validar temporalmente para evitar leakage—já experimentou testar diferentes janelas de validação temporal?