Dane w „drugim zestawie” są trochę inne. Jest to plik csv, gdzie wartości oddzielone są średnikiem, zawierający trzy kolumny:
Informacje poprzedzone są czterolinikowym nagłówkiem — w pierwszej chwili zupełnie nieistotnym.
Do importu ponownie użyjemy funkcji genfromtxt
z pakietu numpy
.
Ponieważ zawartość drugiej kolumny nie jest „zrozumiała” dla funkcji — wstawia ona tam wartości NaN.
import numpy as np
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.dates as md
plt.rcParams["figure.figsize"] = (12,9) # Tu definiujemy rozmiary wykresu.
# Standardowo wydaje się być zbyt mały.
dane=np.genfromtxt('Outdoor_temperature_2017-09.csv',skip_header=4,delimiter=';')
Zacznijmy od szybkiego obejrzenia danych
plt.plot(dane[:,0], dane[:,2], '.')
plt.show()
Współrzędna $x$ to (najprawdopodobniej) unixowy timestamp — można zastosować rozwiazanie sprawdzone wcześniej.
dates=[dt.datetime.fromtimestamp(ts) for ts in dane[:,0]]
plt.xticks( rotation=25 )
ax = plt.gca()
xfmt = md.DateFormatter('%Y-%m-%d')
ax.xaxis.set_major_formatter(xfmt)
plt.plot(dates, dane[:,2], '.')
plt.show()
min(dates)
datetime.datetime(2017, 9, 1, 0, 2, 56)
min(dane[:,0])
1504216976.0
plt.plot(dane[:,0] - min(dane[:,0]), dane[:,2], '.')
plt.show()
Chcąc zbadać na ile zmiany temperaturu w ciągu miesiąca są okresowe można spróbować wyznaczyć transformatę Fouriera i zbadać dominującą składową.
Niestety związane jest to z wielu problemami.
W naszym przypadku mamy tyle punktów danych:
dane.shape[0]
8565
Pochodzą one z jednego miesiaca (w przykładzie września), który ma 30 dni czyli
30 * 24 * 60 * 60/dane.shape[0]
302.62697022767077
były wykonywane średnio co około 5 minut (303 sekundy). Wydaje się, że pomiary co godzinę (albo nawet i dwie) wystarczą do naszej analizy. Teoretycznie możnaby wyrzucić wszystkie wartości pośrednie i dobrać pomiary z, mniej-więcej, całych godzin. Lepiej jednak użyć interpolacji.
Co więcej, zwracam uwagę, że nie interesuje nas czas bezwzględny tylko raczej względny gdzie pierwszy pomiar wykonany został w chwili zero, kolejny w sekundzie 3600 (po godzinie) i tak dalej.
Stworzymy nową tablicę zawierającą wartości [0, 3600, 7200,…] obejmującą cały interesujjący nas zakres (miesiąc).
min(dane[:,0])
to minimalny indeks czasowy danych, a max(dane[:,0])
to maksymalny indeks czasowy
zakres=max(dane[:,0]) - min(dane[:,0])
Funkcja np.arange()
tworzy tablicę danych z zadanym krokiem obejmującą swoim zakresem analizowany mmiesiąc.
czas=np.arange(0, zakres, 7200)
Funkcja np.interp()
na podstawie danych wylicza dla całego wektora czas
wartości funkcji (używając interpolacji liniowej) jeżeli to niezbędne.
temperatura = np.interp(czas, dane[:,0] - min(dane[:,0]), dane[:,2])
plt.plot(czas,temperatura)
plt.show()
czas.shape
(360,)
Operacja zmiany odstępu czasu pomiędzy próbkami nazywana jest resamplingiem. Przy czym, jeżeli częstość pomiarów zwiększamy — jest tu upsampling, a gdy zmniejszamy — downsampling.
Gdy pomiary są już dokonane ze stałym krokiem do down- i up-samplingu można wykorzystać interpolację trygonometryczną (realizowaną z użyciem FFT). Gdy pomiary — tak jak w tym przypadku — wykonywane są nieregularnie — pozostaje interpolacja.