Pular para o conteúdo principal

Tutorial de análise de séries temporais com Python

Obtenha dados do Google Trends para termos como "diet" e "gym" e veja como variam ao longo do tempo enquanto aprende sobre tendências e sazonalidade em séries temporais.
Atualizado 17 de set. de 2026  · 15 min lido

Explorar com IA

ChatGPTClaudePerplexity

Na sessão de code along no Facebook Live do dia 4 de janeiro, analisamos os dados do Google Trends para as palavras-chave "diet", "gym" e "finance" para ver como elas variam ao longo do tempo. Perguntamos: será que há mais buscas por esses termos em janeiro, quando todo mundo quer começar o ano com o pé direito?

Neste tutorial, você vai percorrer, passo a passo, o código que montamos durante a sessão. Não vamos focar em matemática pesada. A ênfase aqui é uma exploração visual do conjunto de dados em questão.


Para saber mais sobre pandas, confira a trilha de aprendizado Data Manipulation with Python da DataCamp. Para mais conteúdo sobre séries temporais com pandas, veja o curso Manipulating Time Series Data in Python.

Importando pacotes e dados

Então a pergunta permanece: será que há mais buscas por esses termos em janeiro, quando estamos tentando começar uma nova fase?

Vamos descobrir acessando este link e conferindo os dados. Observação: este tutorial foi inspirado nesta matéria do FiveThirtyEight.

Você também pode baixar os dados em .csv, salvar em um arquivo e importar no seu próprio ambiente Python para fazer sua análise. Vamos fazer isso agora. Mãos à obra!

Para começar, importe alguns pacotes: neste caso, vamos usar numpy, pandas, matplotlib e seaborn.

Além disso, se quiser que as imagens sejam exibidas no Jupyter Notebook, use o magic do IPython adicionando %matplotlib inline ao seu código. Como alternativa, você também pode ativar os padrões do Seaborn com sns.set():

# Import packages
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set()

Importe os dados que você baixou com .read_csv() e visualize as primeiras linhas com .head().

Observação: adicione o argumento skiprows para pular a primeira linha do arquivo.

 df = pd.read_csv('data/multiTimeline.csv', skiprows=1)
df.head()
  Month diet: (Worldwide) gym: (Worldwide) finance: (Worldwide)
0 2004-01 100 31 48
1 2004-02 75 26 49
2 2004-03 67 24 47
3 2004-04 70 22 48
4 2004-05 72 22 43

Você também pode usar o método .info() para conferir os tipos de dados, número de linhas e mais:

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 168 entries, 0 to 167
Data columns (total 4 columns):
Month                   168 non-null object
diet: (Worldwide)       168 non-null int64
gym: (Worldwide)        168 non-null int64
finance: (Worldwide)    168 non-null int64
dtypes: int64(3), object(1)
memory usage: 5.3+ KB

Agora que você importou os dados do Google Trends e deu uma olhada inicial, é hora de tratar os dados e deixá-los no formato ideal para a análise.

Trate seus dados

A primeira coisa é renomear as colunas do seu DataFrame df para remover espaços em branco. Há várias maneiras de fazer isso; por enquanto, vamos atribuir a df.columns uma lista com os novos nomes das colunas.

Confira o resultado chamando df.head():

df.columns = ['month', 'diet', 'gym', 'finance']
df.head()
  month diet gym finance
0 2004-01 100 31 48
1 2004-02 75 26 49
2 2004-03 67 24 47
3 2004-04 70 22 48
4 2004-05 72 22 43

Em seguida, transforme a coluna 'month' em DateTime e use-a como índice do DataFrame.

Observação: fazemos isso porque, no resultado de .info(), vimos que a coluna 'Month' era do tipo object, que é genérico (pode ser string, inteiro etc.). Para séries temporais, isso não é o ideal. Por isso, usamos .to_datetime() para converter a coluna 'month' em DateTime.

Atenção! Inclua o argumento inplace ao definir o índice do DataFrame df para realmente alterar o índice original e defini-lo como a coluna 'month'.

df.month = pd.to_datetime(df.month)
df.set_index('month', inplace=True)
df.head()
  diet gym finance
month      
2004-01-01 100 31 48
2004-02-01 75 26 49
2004-03-01 67 24 47
2004-04-01 70 22 48
2004-05-01 72 22 43

Agora é hora de explorar seu DataFrame visualmente.

Um pouco de análise exploratória (EDA)

Você pode usar o método de visualização do pandas, .plot(), para criar 3 gráficos de linha em uma única figura (um para cada coluna: 'diet', 'gym' e 'finance').

Dica: é possível especificar argumentos como figsize, linewidth e fontsize para ajustar o tamanho da figura, a espessura da linha e o tamanho da fonte, respectivamente.

Além disso, repare que o eixo x exibe anos (e não meses, como o rótulo padrão pode sugerir). Para deixar o gráfico mais fiel, altere o rótulo do eixo x para 'Year' e defina o tamanho da fonte como 20.

Truque: se quiser suprimir a saída do Matplotlib, basta adicionar um ponto e vírgula ; na última linha!

df.plot(figsize=(20,10), linewidth=5, fontsize=20)
plt.xlabel('Year', fontsize=20);

pandas visualization line graph

Observação: esses dados são relativos. Como explicado no Google Trends:

Os números representam o interesse de pesquisa em relação ao ponto mais alto do gráfico para a região e o período selecionados. Um valor de 100 indica pico de popularidade do termo. Um valor de 50 significa metade da popularidade. Um valor 0 significa que o termo teve menos de 1% da popularidade do pico.

Se quiser, você também pode plotar apenas a coluna 'diet' como uma série temporal:

df[['diet']].plot(figsize=(20,10), linewidth=5, fontsize=20)
plt.xlabel('Year', fontsize=20);

pandas visualization graph time series

Observação: a primeira coisa a notar é a sazonalidade: todo mês de janeiro há um grande salto. Também parece haver uma tendência: sobe um pouco, depois cai, volta a subir e então cai de novo. Em outras palavras, há componentes de tendência e sazonais nessas séries temporais.

Com isso em mente, vamos aprender a identificar tendências na sua série temporal!

Tendências e sazonalidade em séries temporais

Identificando tendências em séries temporais

Há várias maneiras de identificar tendências em séries temporais. Uma bastante usada é a média móvel (rolling average), em que, para cada ponto no tempo, você calcula a média dos pontos ao seu redor. O número de pontos é definido por uma janela (window size) que você precisa escolher.

Ao tirar a média, você tende a suavizar ruídos e a sazonalidade. Veja um exemplo agora com a média móvel de 'diet' usando métodos nativos do pandas.

Como estamos falando de sazonalidade anual, faz sentido começar testando uma janela de doze meses.

diet = df[['diet']]
diet.rolling(12).mean().plot(figsize=(20,10), linewidth=5, fontsize=20)
plt.xlabel('Year', fontsize=20);

time series graph

Observação: no trecho de código acima, usamos dois colchetes para extrair a coluna 'diet' como um DataFrame; se usássemos um só, como em df['diet'], teríamos criado uma Series do pandas.

Nesse código, também encadeamos métodos (method chaining): chamamos métodos em sequência sobre um objeto. Esse estilo é bem popular e o pandas dá ótimo suporte a ele!

Agora você tem a tendência que buscava! Grande parte da sazonalidade foi removida em comparação ao gráfico anterior.

Você também pode plotar a média móvel de 'gym' com a mesma janela usada para 'diet':

gym = df[['gym']]
gym.rolling(12).mean().plot(figsize=(20,10), linewidth=5, fontsize=20)
plt.xlabel('Year', fontsize=20);

time series graph 2

Conseguimos remover a sazonalidade e vemos uma tendência de alta para "gym"! Mas como esses dois termos se comparam?

Você pode descobrir isso plotando as tendências de 'gym' e 'diet' na mesma figura:

df_rm = pd.concat([diet.rolling(12).mean(), gym.rolling(12).mean()], axis=1)
df_rm.plot(figsize=(20,10), linewidth=5, fontsize=20)
plt.xlabel('Year', fontsize=20);

time series graph 3

Criamos um novo DataFrame, df_rm, com duas colunas contendo as médias móveis de 'diet' e 'gym'. Usamos pd.concat(), que recebe uma lista de colunas como primeiro argumento e, como queremos concatenar por colunas, definimos axis=1.

Depois, plotamos o DataFrame com plot(), como antes! Removendo a sazonalidade, vemos que diet pode ter algum comportamento cíclico, enquanto gym está de fato em alta!

Com as tendências identificadas, é hora de analisar a sazonalidade, ou seja, a natureza repetitiva da sua série temporal. Como vimos no começo, parecia haver componentes de tendência e sazonais nos dados.

Padrões sazonais em séries temporais

Uma forma de analisar os componentes sazonais é remover a tendência da série, facilitando a investigação da sazonalidade. Para isso, você pode subtrair a tendência (média móvel) do sinal original. Porém, o resultado depende do tamanho da janela usada.

Outra forma é o "differencing" (diferenças), em que você observa a diferença entre pontos sucessivos ("diferença de primeira ordem", pois olha a diferença entre um ponto e seu antecessor).

Diferença de primeira ordem

Use pandas com os métodos diff() e plot() para calcular e plotar a diferença de primeira ordem da Series 'diet':

diet.diff().plot(figsize=(20,10), linewidth=5, fontsize=20)
plt.xlabel('Year', fontsize=20);

time series graph 3

Perceba que boa parte da tendência foi removida e os picos de janeiro de cada ano ficam bem evidentes. Todo janeiro há um salto enorme de 20% ou mais no termo com maior volume de buscas!

Observação: você também pode aplicar diferenças de 2ª ordem (diferença entre um ponto e os dois anteriores) se a tendência ainda não tiver sido totalmente removida. Veja mais detalhes aqui.

O differencing é muito útil para transformar sua série em estacionária. Sem entrar a fundo, uma série estacionária é aquela cujas propriedades estatísticas (como média e variância) não mudam no tempo. Elas são úteis porque muitos métodos de previsão assumem estacionariedade.

Com isso em mãos, vamos analisar a periodicidade da sua série olhando a função de autocorrelação. Antes, porém, um breve desvio sobre correlação.

Periodicidade e autocorrelação

Uma série temporal é periódica quando se repete em intervalos regulares, por exemplo, a cada 12 meses.

Outra forma de pensar: se a série tem um pico em algum ponto, haverá um pico 12 meses depois; se há um vale, outro vale aparecerá 12 meses depois.

Mais uma visão: a série é correlacionada com ela mesma deslocada em 12 meses. Ou seja, se você mover a série 12 meses para trás ou para frente, ela se "alinha" consigo mesma de alguma forma.

Considerar a correlação de uma série com uma versão deslocada dela é justamente o conceito de autocorrelação.

Já vamos chegar lá.

Antes, vamos relembrar rapidamente o que é correlação de forma intuitiva!

O coeficiente de correlação entre duas variáveis captura o quanto elas se relacionam linearmente. Para entender melhor, vamos a um exemplo prático com o conjunto de dados iris, que contém medidas de flores.

Para isso, importe o conjunto iris do scikit-learn, transforme-o em um DataFrame e visualize as primeiras linhas com .head():

from sklearn import datasets
iris = datasets.load_iris()
df_iris = pd.DataFrame(data= np.c_[iris['data'], iris['target']],
                     columns= iris['feature_names'] + ['target'])
df_iris.head()
  sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
0 5.1 3.5 1.4 0.2 0.0
1 4.9 3.0 1.4 0.2 0.0
2 4.7 3.2 1.3 0.2 0.0
3 4.6 3.1 1.5 0.2 0.0
4 5.0 3.6 1.4 0.2 0.0

Relembrando: toda flor tem sépala e pétala. A sépala envolve as pétalas e costuma ser verde e semelhante a uma folha; as pétalas são as "folhas" coloridas. A coluna 'target', variável-alvo, representa a espécie das íris (Versicolor, Virginica ou Setosa), codificadas como 0, 1 e 2 na tabela.

Agora, para pensar em correlação, vamos ver como o comprimento da sépala se correlaciona com a largura da sépala. Para isso, use pandas ou seaborn para criar um scatter plot de 'sepal length' versus 'sepal width':

sns.lmplot(x='sepal length (cm)', y='sepal width (cm)', fit_reg=False, data=df_iris);

correlation graph

Observação: desativamos a regressão linear definindo fit_reg=False.

O comprimento e a largura da sépala são positiva ou negativamente correlacionados no conjunto todo? E dentro de cada espécie? Essa distinção é essencial.

No primeiro caso, conforme o comprimento aumenta, a largura também aumenta de forma linear. No segundo, conforme o comprimento aumenta, a largura diminui linearmente.

À primeira vista, o gráfico sugere uma correlação negativa: conforme o comprimento aumenta, a largura diminui levemente.

Agora, vamos criar um scatter plot de 'sepal length' versus 'sepal width', colorindo pelos valores de species (target):

sns.lmplot(x='sepal length (cm)', y='sepal width (cm)', fit_reg=False, data=df_iris, hue='target');

correlation graph 2

À primeira vista, o gráfico acima sugere correlação positiva: dentro de cada espécie, quando o comprimento aumenta, a largura também aumenta.

Visualizações ajudam a construir intuição sobre correlação, mas também é útil calcular o coeficiente de correlação.

Você pode calcular os coeficientes de correlação de cada par de medidas com .corr():

df_iris.corr()
  sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) target
sepal length (cm) 1.000000 -0.109369 0.871754 0.817954 0.782561
sepal width (cm) -0.109369 1.000000 -0.420516 -0.356544 -0.419446
petal length (cm) 0.871754 -0.420516 1.000000 0.962757 0.949043
petal width (cm) 0.817954 -0.356544 0.962757 1.000000 0.956464
target 0.782561 -0.419446 0.949043 0.956464 1.000000

Observação: "sepal length (cm)" e "sepal width (cm)" parecem negativamente correlacionados no conjunto total (coeficiente -0,1). No entanto, dentro de cada espécie, a correlação não é negativa — chega a 0,78.

Para quem se interessar, isso é conhecido como paradoxo de Simpson e é crucial ao pensar em inferência causal. Leia mais aqui.

Vamos explorar mais: vamos calcular os coeficientes de correlação de cada par de medidas dentro de cada espécie. Para isso, encadeie .groupby() e .corr() para agrupar por target e calcular a correlação:

df_iris.groupby(['target']).corr()
    petal length (cm) petal width (cm) sepal length (cm) sepal width (cm)
target          
0.0 petal length (cm) 1.000000 0.306308 0.263874 0.176695
petal width (cm) 0.306308 1.000000 0.279092 0.279973
sepal length (cm) 0.263874 0.279092 1.000000 0.746780
sepal width (cm) 0.176695 0.279973 0.746780 1.000000
1.0 petal length (cm) 1.000000 0.786668 0.754049 0.560522
petal width (cm) 0.786668 1.000000 0.546461 0.663999
sepal length (cm) 0.754049 0.546461 1.000000 0.525911
sepal width (cm) 0.560522 0.663999 0.525911 1.000000
2.0 petal length (cm) 1.000000 0.322108 0.864225 0.401045
petal width (cm) 0.322108 1.000000 0.281108 0.537728
sepal length (cm) 0.864225 0.281108 1.000000 0.457228
sepal width (cm) 0.401045 0.537728 0.457228 1.000000

Nesta matriz de correlação, vemos que:

  • Para o target 0, comprimento e largura da sépala têm correlação de 0,75;
  • Para o target 1, o coeficiente é 0,5; e
  • Para o target 2, a correlação é 0,46.

Todas são correlações positivas (em ordem decrescente) e bem mais altas que a correlação negativa observada no conjunto inteiro.

Isso é muito revelador e reforça a importância de analisar os dados a fundo.

Agora que revisamos correlação, estamos prontos para analisar a periodicidade da sua série olhando a função de autocorrelação!

Para começar, plote todas as séries novamente para relembrar o comportamento:

df.plot(figsize=(20,10), linewidth=5, fontsize=20)
plt.xlabel('Year', fontsize=20);

time series graph 4

Depois, calcule os coeficientes de correlação entre todas as séries com .corr():

df.corr()
  diet gym finance
diet 1.000000 -0.100764 -0.034639
gym -0.100764 1.000000 -0.284279
finance -0.034639 -0.284279 1.000000

O que isso nos diz?

Focando em 'diet' e 'gym': elas são negativamente correlacionadas. Interessante! Lembre que temos componentes de tendência e sazonais. Pelo coeficiente, "diet" e "gym" são negativamente correlacionadas. Mas, olhando as séries, parece que os componentes sazonais seriam positivamente correlacionados e as tendências, negativamente.

O coeficiente de correlação está capturando ambos.

Agora queremos plotar as diferenças de primeira ordem dessas séries e então calcular a correlação entre elas, o que aproxima a correlação dos componentes sazonais. Remover a tendência pode revelar correlação na sazonalidade.

Comece plotando as diferenças de primeira ordem com .diff() e .plot():

df.diff().plot(figsize=(20,10), linewidth=5, fontsize=20)
plt.xlabel('Year', fontsize=20);

time series graph 5

Você vê que 'diet' e 'gym' ficam altamente correlacionadas após remover a tendência. Agora, calcule os coeficientes de correlação das diferenças de primeira ordem dessas séries:

df.diff().corr()
  diet gym finance
diet 1.000000 0.758707 0.373828
gym 0.758707 1.000000 0.301111
finance 0.373828 0.301111 1.000000

Observação: antes, ao considerar tendência e sazonalidade juntas, vimos leve correlação negativa. Agora, considerando o componente sazonal, 'diet' e 'gym' estão altamente correlacionadas (coeficiente 0,76).

Autocorrelação

Depois de explorar correlação entre variáveis e séries, vamos plotar a autocorrelação da série 'diet': no eixo x, o lag; no eixo y, o quanto a série se correlaciona consigo mesma nesse lag.

Se a série se repete a cada dois dias, esperamos um pico na função de autocorrelação em 2 dias.

Aqui, esperamos um pico em 12 meses: a série é correlacionada consigo mesma deslocada em doze meses.

Use a interface plotting do pandas, com a função autocorrelation_plot(), para plotar a série 'diet':

pd.plotting.autocorrelation_plot(diet);

autocorrelation plot

Se ampliarmos os lags no eixo, veremos um pico enorme em 12 meses. Há outro pico em 24 meses (e também em 36). Conforme o lag aumenta, a correlação tende a diminuir.

Claro, no lag 0 a correlação é 1 (a série com ela mesma).

As linhas pontilhadas indicam a significância estatística da correlação. Neste caso, podemos dizer que a série 'diet' é genuinamente autocorrelacionada com lag de doze meses.

Identificamos a sazonalidade dessa repetição anual!

Conclusão

Neste tutorial, cobrimos bastante coisa! Analisamos os dados do Google Trends para as palavras "diet", "gym" e demos uma olhada rápida em "finance" para ver como variam no tempo. Abordamos conceitos como sazonalidade, tendências, correlação, autocorrelação...

Para quem quer ir além, aqui vão duas ideias imediatas:

  • Investigue a coluna "finance" e relate o que encontrar;
  • Use modelagem ARIMA para fazer previsões de séries temporais e entender como essas tendências de busca podem evoluir nos próximos anos. O Jason Brownlee, do Machine Learning Mastery, tem um ótimo tutorial sobre ARIMA em Python; na DataCamp há um excelente curso de ARIMA em R e a trilha Time Series with Python.
Tópicos
Python
Ciência de dados
Visualização de dados
Data Analysis

Saiba mais sobre Python

Curso

Análise de séries temporais em Python

4 h
70.6K
Neste curso de quatro horas, você aprenderá os fundamentos da análise de dados de séries temporais em Python.
Ver detalhesRight Arrow
Iniciar Curso
Ver maisRight Arrow
Relacionado

Tutorial

Gráfico de linha de série temporal do Matplotlib

Este tutorial explora como criar e personalizar gráficos de linha de séries temporais no matplotlib.
Elena Kosourova's photo

Elena Kosourova

8 min

Tutorial

Funções em Python: como chamar e escrever funções

Descubra como escrever funções em Python reutilizáveis e eficientes. Domine parâmetros, instruções de retorno e temas avançados como funções lambda. Organize melhor seu código com main() e outras boas práticas.
Karlijn Willems's photo

Karlijn Willems

14 min

Tutorial

Tipos de gráficos de dados e como criá-los em Python

Explore vários tipos de gráficos de dados, desde os mais comuns até os avançados e não convencionais, o que eles mostram, quando usá-los, quando evitá-los e como criá-los e personalizá-los em Python.
Elena Kosourova's photo

Elena Kosourova

15 min

Tutorial

Tutorial de manipulação de dados categóricos de aprendizado de máquina com Python

Aprenda os truques comuns para lidar com dados categóricos e pré-processá-los para criar modelos de aprendizado de máquina!
Moez Ali's photo

Moez Ali

14 min

Tutorial

Tutorial do Python Seaborn Line Plot: Criar visualizações de dados

Descubra como usar o Seaborn, uma biblioteca popular de visualização de dados em Python, para criar e personalizar gráficos de linha em Python.
Elena Kosourova's photo

Elena Kosourova

12 min

Tutorial

Tutorial de execução de scripts Python no Power BI

Descubra as diferentes maneiras de usar o Python para otimizar a análise, a visualização e a modelagem de dados no Power BI.
Joleen Bothma's photo

Joleen Bothma

9 min

Ver MaisVer Mais