Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Controle de Qualidade e Análise de Dados (Analytics)

Este notebook demonstra o uso das ferramentas de análise de dados (módulo analytics) da biblioteca pySINDA. Essas ferramentas facilitam a limpeza de outliers, tratamento de valores faltantes, decomposição do vento em vetores zonais/meridionais, reamostragem temporal e plotagem rápida de séries temporais.

1. Importação das Funções

import numpy as np
import pandas as pd
from pySINDA import (
    clean_data,
    detect_outliers,
    resample_time_series,
    summarize_time_series,
    compute_wind_components
)

try:
    from pySINDA import plot_time_series
    matplotlib_installed = True
except ImportError:
    matplotlib_installed = False
    print("Matplotlib não está instalado no ambiente de execução. A plotagem de gráficos será desabilitada.")

2. Geração de Dados Sintéticos de Teste

Criaremos um dataset fictício de 10 dias com leituras horárias contendo ruído realista, outliers artificiais e alguns valores ausentes para demonstrar a eficácia dos algoritmos de tratamento.

np.random.seed(42)
dates = pd.date_range(start="2023-01-01", periods=240, freq="h")

# Temperatura base com oscilação diurna regular + ruído gaussiano
temperatures = 20 + 6 * np.sin(2 * np.pi * dates.hour / 24) + np.random.normal(0, 0.4, len(dates))
# Vento com distribuição exponencial
wind_speed = np.random.exponential(scale=3.0, size=len(dates))
# Direção do vento em graus
wind_dir = np.random.uniform(0, 360, size=len(dates))

# Inserção de outliers óbvios na Temperatura
temperatures[15] = 48.2  # Valor muito acima da média
temperatures[120] = -8.5 # Valor muito abaixo da média

# Inserção de valores nulos (NaN)
temperatures[50:56] = np.nan
wind_speed[100:106] = np.nan

df = pd.DataFrame({
    'Data': dates,
    'Temperatura': temperatures,
    'VelocidadeVento': wind_speed,
    'DirecaoVento': wind_dir
})

print(f"Dataset gerado com sucesso: {len(df)} linhas.")
df.head(10)

3. Sumário Estatístico da Série Temporal

A função summarize_time_series analisa a série temporal e retorna estatísticas globais e por variável, detalhando inclusive a porcentagem de valores nulos.

summary = summarize_time_series(df, time_col='Data')
print("=== Informações Gerais ===")
print(f"Início do período: {summary['start_time']}")
print(f"Fim do período: {summary['end_time']}")
print(f"Total de registros: {summary['total_records']}")
print(f"Duração temporal: {summary['duration']}")

print("\n=== Estatísticas por Variável ===")
for col, stats in summary['variables'].items():
    print(f"\nSensor: {col}")
    print(f"  Média aritmética: {stats['mean']:.2f}")
    print(f"  Desvio padrão: {stats['std']:.2f}")
    print(f"  Mínimo detectado: {stats['min']:.2f}")
    print(f"  Máximo detectado: {stats['max']:.2f}")
    print(f"  Valores ausentes: {stats['missing_count']} ({stats['missing_percentage']:.2f}%)")

4. Detecção e Tratamento de Outliers e Nulos

Vamos identificar posições com valores discrepantes usando detect_outliers (baseado em Z-score) e, em seguida, fazer a limpeza e interpolação linear dos dados faltantes e anômalos usando clean_data.

# Detectar outliers na coluna de Temperatura com Z-score acima de 3
outliers_mask = detect_outliers(df, columns=['Temperatura'], threshold=3.0)
print(f"Número de outliers de temperatura identificados: {outliers_mask['Temperatura'].sum()}")

# Visualizar as linhas onde os outliers estão
print("\nOutliers originais no dataset:")
print(df[outliers_mask['Temperatura']])

# Realizar o tratamento completo (substitui outliers por NaN + interpolação linear)
df_cleaned = clean_data(df, time_col='Data', fill_method='interpolate', outlier_threshold=3.0)

print("\nDados limpos e corrigidos nas mesmas posições:")
print(df_cleaned.loc[outliers_mask['Temperatura'].index[outliers_mask['Temperatura']]])

5. Decomposição de Componentes do Vento

Para análises físicas de transporte e modelagem, é comum decompor a velocidade e direção do vento nas componentes zonais (wind_U, Leste-Oeste) e meridionais (wind_V, Norte-Sul) usando trigonometria.

df_wind = compute_wind_components(df_cleaned, speed_col='VelocidadeVento', dir_col='DirecaoVento')
print("Componentes de vento calculadas (wind_U, wind_V):")
df_wind[['VelocidadeVento', 'DirecaoVento', 'wind_U', 'wind_V']].head(10)

6. Reamostragem Temporal (Resampling)

Utilizaremos resample_time_series para agrupar e condensar os dados horários em médias diárias (rule='D'), o que suaviza ruídos de alta frequência.

df_daily = resample_time_series(df_wind, time_col='Data', rule='D', agg='mean')
print("Resumo diário dos dados (médias):")
df_daily

7. Visualização de Séries Temporais

Se você possui a biblioteca matplotlib instalada, pode usar plot_time_series para visualizar as variáveis.

if matplotlib_installed:
    # Plota a comparação entre dados originais (com outliers/ruído) e dados limpos
    plot_time_series(df_cleaned, time_col='Data', variables=['Temperatura', 'VelocidadeVento'])
else:
    print("Instale o matplotlib para gerar as visualizações: pip install matplotlib")