As enchentes do Rio Nilo

Os dados que vamos utilizar são médias mensais de ? para os anos de 1970 até 1984.


In [ ]:
from pandas import Series, read_csv

FN = read_csv('../../data/nile_rover_flood.csv', index_col='year', na_values='-9999.0', usecols=range(13))
FN.head(5)

In [ ]:
from datetime import datetime
from pandas import Series

# Junta tudo em uma série temporal.
years = FN.index.values.astype(int)
months = FN.columns.values.astype(str)
date = []
for year in years:
    for month in months:
        date.append(datetime.strptime('%s %s' % (year, month), '%Y %b'))
        
flood = Series(FN.values.ravel(), index=date)

In [ ]:
ax = flood.plot(figsize=(12, 4))
_ = ax.set_title('Full dataset')

Agora amos plotar todas as curvas para cada ano uma sobre a outra.


In [ ]:
data = FN.T
ax = data.plot(legend=False)
_ = ax.set_title('Yearly curves overlapped')

Transformada de Fourier discreta

Nós queremos estudar a ocorrência de inundações do rio Nilo. Para isso vamos usar nossa ferramenta favorita: a DFT.

$$ X_k = \sum_{n=0}^{N-1} x_n e^{j2\pi \frac{nk}{N}} $$

In [ ]:
from numpy.fft import fft

N = len(flood)

F = fft(flood.dropna() - flood.mean())

F = F[:N / 2 + 1]  # Já que o sinal é real, podemos manter apenas uma metade do espectro.

Ao invés de usar um índice linear do vetor, nós queremos saber a qual frequência cada ponto corresponde. A diferença da frequência em dois pontos na DFT é $N/T$.


In [ ]:
import numpy as np

total_time = (flood.index[-1] - flood.index[0]).total_seconds() / (60 * 60 * 24 * 30 * 12)
freq = np.arange(0, N / 2 + 1) / total_time

In [ ]:
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot(freq, np.abs(F))
ax.set_xlabel('1/year')
ax.set_ylabel('|dft(A)|')
_ = ax.set_xlim(-0.1, 6.1)