Visualizzazione post con etichetta Pandas. Mostra tutti i post
Visualizzazione post con etichetta Pandas. Mostra tutti i post

venerdì 17 gennaio 2025

Pandas su serie tempo

Problema: hai un csv che riporta una serie tempo datetime/valore di un sensore

Effettuare calcoli, ordina le righe, ricampiona il passo temporale, colma i buchi della serie tempo con interpolazione in modo semplice

Data;Valore_p
2024-07-24 12:42:05;0
2024-07-24 12:44:05;0
2024-07-24 12:46:05;0

 soluzione : usa Pandas di Python

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import argrelextrema


#legge i dati dal csv
df_b = pd.read_csv('battente.csv', sep=';',header=0, parse_dates = ['Data'], date_format = '%Y-%m-%d %H:%M:%S')
#ricampiona i dati con un dato al giorno usando il valore medio
df_b_res = df_b.resample('1h', on='Data').mean()
#df_b.iloc[:,1] = df_b.iloc[:,1].apply(lambda x: (x-x.mean())/ x.std())
print(df_b)



df_p = pd.read_csv('pluviometro.csv', sep=';',header=0, parse_dates = ['Data'], date_format = '%Y-%m-%d %H:%M:%S')
#df_p = df_p.shift(periods=3)
df_p_res = df_p.resample('1h', on='Data').mean()

#unisce i due file usando come chiave la colonna temporale
merged_dataframe = pd.merge_asof(df_p_res, df_b_res, on="Data")
#rimuove le righe in cui non ci sono valori
df_finale = merged_dataframe.dropna(how='any')


#cerca i massimi locali facendo scorrere una finestra di 12 ore
df_finale['local_max_p'] = df_finale.iloc[argrelextrema(df_finale.Valore_p.values, np.greater_equal,order=12)[0]]['Valore_p']
df_finale['local_max_b'] = df_finale.iloc[argrelextrema(df_finale.Valore_b.values, np.greater_equal,order=12)[0]]['Valore_b']

#elimina i massimi locali che sono sotto ad una soglia
df_finale['local_max_p'] = np.where(df_finale["local_max_p"] < 1.0,np.nan,df_finale["local_max_p"])
df_finale['local_max_b'] = np.where(df_finale["local_max_b"] < 1.0,np.nan,df_finale["local_max_b"])

df_finale.to_csv("allineato.csv", sep=";")


fig, ax1 = plt.subplots()
# Plot first time series on the primary axis
ax1.plot(df_finale['Data'], df_finale['Valore_b'], 'g-')
ax1.plot(df_finale['Data'], df_finale['local_max_b'], 'mo')

ax1.set_xlabel('Data')
ax1.set_ylabel('Battente (m)', color='g')
ax2 = ax1.twinx()
ax2.plot(df_finale['Data'], df_finale['Valore_p'], 'b-')
ax2.plot(df_finale['Data'], df_finale['local_max_p'], 'ro')

ax2.set_ylabel('Prec.(mm)', color='b')
plt.savefig('grafico.png')
plt.show()






lunedì 14 ottobre 2024

Inner Join con Pandas

 Avevo la necessita' di unire due file csv (misura di tempo; misura del sensore) ma i due sensori hanno avuto dei fermi per cui non era sufficiente mettere le colonne affiancate ed era necessaria una inner join (ma sulla macchine di lavoro non ho accesso un sql server) ..sono oltre 85000 dati quindi e' escluso fare a mano

La libreria Pandas e' venuta in aiuto




CSV Portata

tempo;valore
38923.54;37
38923.58;36
38923.63;36
38923.67;36

CSV Tordibita

tempo;valore
38923.54;0
38923.58;0


import pandas as pd
from matplotlib import pyplot as plt

por = pd.read_csv('portata.csv',sep=';')
tor = pd.read_csv('torbidita.csv',sep=';')
por['tempo'] = por['tempo'].astype(str)
tor['tempo'] = tor['tempo'].astype(str)

unione = por.merge(tor, on="tempo", how='inner')
unione.plot(
x='valore_x',
xlabel='Portata',
y='valore_y',
ylabel='Torbidita',
title= '25/07/06 - 27/02/2017',
kind='scatter'
)
plt.show()
#unione.to_csv("unione.csv", sep=';')


venerdì 12 gennaio 2024

Animazione di grafico con Matplotlib

 







import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import pandas as pd
df = pd.read_csv("tempo.csv", dtype=str,sep=";")
print(df)
my_data = np.genfromtxt('./scatterplot.csv', delimiter=';')
x = my_data[:,1]
y = my_data[:,0]
fig = plt.figure()
ax = fig.add_subplot()
plt.ylim(-5, 22)
plt.ylabel ('Temperatura (C)')
plt.xlim(-59, -53)
plt.xlabel ('Estensimetro (mm)')
tempo = ax.text(0.8, 0.9, '', horizontalalignment='center',verticalalignment='center', transform=ax.transAxes)
graph, = plt.plot([], [], 'o', markersize=1)
def animate(i):
    graph.set_data(x[:i+1], y[:i+1])
    tempo.set_text(df.Data[i])
    return graph,
ani = FuncAnimation(fig, animate, frames=2000, interval=50)
#FFwriter = animation.FFMpegWriter(fps=10)
#ani.save('animation.mp4')
plt.show()

giovedì 23 dicembre 2021

Correlazione tra serie tempo

 Un semplice script che calcola la correlazione tra due serie tempo (due estensimetri) facendo scorrere una finestra mobilew    


Come si vede il versante si muove con costanza in modo uniforme (i due estensimetri hanno dati correlabili)...quando c'e' una accelerazione questa e' locale e fa decorrelare i due punti di misura. In seguito si reinstaura il movimento generale

I dati meteo sono sostanzialmente inutili perche' in inverno le precipitazioni sono unicamente nevose. Nel resto dell'anno le precipitazioni non sembrano avere una particolare stagionalita'


import datetime as dt
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt

from sklearn.preprocessing import PolynomialFeatures

from scipy import signal

## tutti i dati sono ricampionamti su base giornaliera
## i dati sono campionati ogni 20 oppure ogni 15 minuti
## i dati radar sono campionati ogni 70 minuti

################### METEO ################################
## dal 24/7/2019 00;00 al 1/12/2021 23:59
parser = lambda date: dt.datetime.strptime(date, '%d/%m/%Y %H:%M')
meteo = pd.read_csv('meteo/meteo.csv', sep=';', parse_dates=['Data'], index_col=['Data'], infer_datetime_format=True)

#effettua il resampling sui 180 minuti
meteo_d = meteo.resample('180T').sum()
meteo_d.to_csv("meteo_180.csv")

print(meteo_d.shape)

#################### RADAR ###############################
parser = lambda date: dt.datetime.strptime(date, '%d/%m/%Y %H:%M:%S.%f')
# legge il csv e lo mette in un dataframe
dati_s1 = pd.read_csv('disp_raw_PTS_P2.csv', sep=',', parse_dates=['Tempo'], index_col=['Tempo'], date_parser=parser)
dati_s2 = pd.read_csv('disp_raw_PTS_P30.csv', sep=',', parse_dates=['Tempo'], index_col=['Tempo'], date_parser=parser)
# ricampiona in base giornaliera
dati_s1_d = dati_s1.resample('180T').mean()
dati_s2_d = dati_s2.resample('180T').mean()
#estrae solo i dati per i quali c'e' anche il dato meteo
#dati_s1_d_f = dati_s1_d[246:1107]
#dati_s2_d_f = dati_s1_d[246:1107]

#salva su file
dati_s1_d.to_csv("s1.csv")
dati_s2_d.to_csv("s2.csv")

# finestra mobile
mw = []
x1 = np.arange(862)

for i in range(1950,8846):
set1 = dati_s1_d[i-160:i]
set2 = dati_s2_d[i-160:i]
mw_v = np.corrcoef(set1.iloc[:,0],set2.iloc[:,0])
mw.append(mw_v[0,1])

plt.figure()

plt.subplot(311)
plt.plot(meteo_d.index,dati_s1_d[1950:8846], color='green', label='P2')
plt.plot(meteo_d.index,dati_s2_d[1950:8846], color='blue', label='P30')
plt.legend()

plt.xlabel('Tempo')
plt.ylabel('Raw Radar (mm)')
plt.title('P2 P30')


plt.subplot(312)
plt.plot(meteo_d.index,mw, color='red')

plt.xlabel('Tempo')
plt.ylabel('Indice corr.')


plt.subplot(313)
plt.bar(meteo_d.index,meteo_d['Pluv.[mm]'])
plt.xlabel('Tempo')
plt.ylabel('Prec. (mm)')
plt.show()

#### ricerca del lag
print("########lag")
correlation = signal.correlate(dati_s1_d-np.mean(dati_s1_d), dati_s2_d - np.mean(dati_s2_d), mode="full")
lags = signal.correlation_lags(len(dati_s1_d), len(dati_s2_d), mode="full")
lag = lags[np.argmax(correlation)]
print(lag)


Pandas su serie tempo

Problema: hai un csv che riporta una serie tempo datetime/valore di un sensore Effettuare calcoli, ordina le righe, ricampiona il passo temp...