7. LoRaWan – Correlación de medidas vs estación meteorológica

La matriz de correlación entre los parámetros de propagación observados y las variables de clima de una estación meteorológica se puede procesar con Python.

Se dispone de las descripciones estadísticas de Rssi obtenidas en cada punto sobre una línea de propagación usadas para estimar el modelo de propagación para esa ruta.

Por otra parte también se dispone de las lecturas de una estación meteorológica cercana al lugar de mediciones.

La primera parte del proceso consiste en leer los archivos en diferentes tablas, para seguir un procedimiento donde se emparejan los valores de las variables a usar. El emparejamiento se realiza buscando la fecha y hora mas cercana usando la instrucción de Pandas dataframe.

    fechap = tablaPt['publishedAt'][i]
    donde  = tablaEM['fecha'].searchsorted(fechap)

La matriz de correlación  se calcula usando la librería Pandas para mantener un formato de columnas de lectura sencilla. Los datos en columnas a usar se agrupan en una tabla «mediciones» para realizar la llamada a corr().

correlacion_matriz = mediciones.corr()

la tabla de correlación que se obtiene:

Matriz de correlación: m_MD10
             rssi_up  rssi_down      TEMP  Humidity  Solar_rad  Bar_press.  Rainfall
rssi_up     1.000000   0.062009 -0.103856  0.050208  -0.079344    0.172215       NaN
rssi_down   0.062009   1.000000 -0.058020 -0.004584   0.002753    0.158011       NaN
TEMP       -0.103856  -0.058020  1.000000 -0.972939   0.841263   -0.673707       NaN
Humidity    0.050208  -0.004584 -0.972939  1.000000  -0.819612    0.618423       NaN
Solar_rad  -0.079344   0.002753  0.841263 -0.819612   1.000000   -0.361084       NaN
Bar_press.  0.172215   0.158011 -0.673707  0.618423  -0.361084    1.000000       NaN
Rainfall         NaN        NaN       NaN       NaN        NaN         NaN       NaN

La matriz de correlación se aplica para cada punto.

Instrucciones en Python

# Archivos de sensores y estación meteorologica
# correlacion entre medida_Punto y sensor_EM
import numpy as np
import pandas as pd
import datetime as dt
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, DayLocator

# INGRESO
# tabla punto
archivoPunto = "data_m_MD10.csv"
medida_Punto = ["rssi_up","rssi_down"]
medida_Punto_u = ["(dBm)","(dBm)"]

# tabla estacion meteorologica
archivoEM = "2021_10a12EstMeteorologica.csv"
sensor_EM = ["TEMP","Humidity","Solar_rad",
             "Bar_press.","Rainfall"]
sensor_EM_u = ["(°C)","(%)","(kW)",
               "(hPa)","(mm)"]

# carpeta de resultados
carpeta_rsm = "correlacion_rsm"

# PROCEDIMIENTO
# tabla punto
tablaPt = pd.read_csv(archivoPunto)
tablaPt = tablaPt.drop(columns='Unnamed: 0')
tablaPt = pd.DataFrame(tablaPt)
tablaPt_n = len(tablaPt)
fechaformatoPt = "%Y-%m-%d %H:%M:%S.%f"
tablaPt['publishedAt'] = pd.to_datetime(tablaPt['publishedAt'],
                                      format=fechaformatoPt)
# tabla estacion meteorologica
tablaEM = pd.read_csv(archivoEM, sep=';',decimal=',')
tablaEM = pd.DataFrame(tablaEM)
tablaEM_n = len(tablaEM)
fechaformatoEM = "%d/%m/%Y %H:%M:%S"
tablaEM['fecha'] = tablaEM['Date']+' '+tablaEM['Time']
tablaEM['fecha'] = pd.to_datetime(tablaEM['fecha'],
                                  format=fechaformatoEM)

# intersecta tablas: punto con estacion meteorologica
# columnas vacias
for j in range(0,len(sensor_EM),1):
    tablaPt[sensor_EM[j]] = np.NAN
# busca fecha y hora mas cercana
for i in range(0,tablaPt_n-1,1):
    fechap = tablaPt['publishedAt'][i]
    donde  = tablaEM['fecha'].searchsorted(fechap)
    if donde<tablaEM_n:
        for j in range(0,len(sensor_EM),1):
            sensor_EMvalor = tablaEM[sensor_EM[j]][donde]
            tablaPt.at[i,sensor_EM[j]] = sensor_EMvalor

# Matriz de Correlación
columnas = medida_Punto.copy()
columnas.extend(sensor_EM)
mediciones = tablaPt[columnas].copy()
correlacion_matriz = mediciones.corr()

# Para graficas
ti  = tablaPt['publishedAt']
medida_graf = {}
untitulo = archivoPunto.split('.')[0][5:]
for i in range(0,len(medida_Punto),1):
    xi = tablaPt[medida_Punto[i]]
    xiavg = np.around(np.average(xi),1)
    xistd = np.around(np.std(xi),2)
    etiq = medida_Punto[i]+' '+str(xiavg)
    etiq = etiq+' +/- '+str(xistd)
    medida_graf[i] = {'medida':xi,'promedio':xiavg,
                      'std':xistd,'etiqueta':etiq}
# SALIDA
print('Matriz de correlación:', untitulo)
print(correlacion_matriz)

# Guarda archivo de matriz de correlación
unresumen = carpeta_rsm+'/'+untitulo+'_correlacion.csv'
tablacorr = correlacion_matriz.round(decimals=4)
tablacorr.to_csv(unresumen)

# Grafica  variable vs tiempo --------
colores = ['blue','orange','green','magenta']
for j  in range(0,len(sensor_EM),1): # cada sensor_EM
    graf_ylim =[]
    fig_Pt, graf_EM = plt.subplots(2,1)
    for i in range(0,len(medida_Punto),1): # cada medida_Punto
        # medida del punto
        graf_EM[i].scatter(ti,medida_graf[i]['medida'],
                           marker = '.',color=colores[i],
                           label=medida_graf[i]['etiqueta'])
        # estacion meteorologica
        eje12 = graf_EM[i].twinx()  # eje de izquierda
        yi = tablaPt[sensor_EM[j]]
        eje12.scatter(ti,yi, marker = '.',
                      color='lightgreen',label=sensor_EM[j])
        # etiquetas
        graf_EM[i].xaxis.set_major_formatter(DateFormatter('%H:%M'))
        etiq_izq = medida_Punto[i]+' '+medida_Punto_u[i]
        graf_EM[i].set_ylabel(etiq_izq, color=colores[i])
        etiq_der = sensor_EM[j]+' '+sensor_EM_u[j]
        eje12.set_ylabel(etiq_der, color='green')
        graf_EM[i].legend()
        graf_ylim.extend(list(graf_EM[i].get_ylim()))

    # ejey subgraficas, limites izquierdo iguales
    y_a = np.min(graf_ylim)
    y_b = np.max(graf_ylim)
    for i in range(0,len(medida_Punto),1):
        graf_EM[i].set_ylim(y_a,y_b)
    # titulos
    titulo_graf = untitulo +': '+medida_Punto[0].split('_')[0]
    titulo_graf = titulo_graf +' vs '+sensor_EM[j]
    graf_EM[0].set_title(titulo_graf)
    fig_Pt.tight_layout()
    # archivo de grafico
    arch_graf = untitulo +'_'+medida_Punto[0].split('_')[0]
    arch_graf = arch_graf +'_'+sensor_EM[j]
    plt.savefig(carpeta_rsm+'/'+arch_graf+'.png')
# plt.show()

# Grafica entre variables --------
for j  in range(0,len(sensor_EM),1): # cada sensor_EM
    fig_Pt, graf_EM = plt.subplots(2,1)
    for i in range(0,len(medida_Punto),1): # cada medida_Punto
        graf_EM[i].scatter(medida_graf[i]['medida'],
                           tablaPt[sensor_EM[j]],
                           marker = '.',color=colores[i])
        # etiquetas
        etiq_x = medida_Punto[i]+' '+medida_Punto_u[i]
        graf_EM[i].set_xlabel(etiq_x, color=colores[i])
        etiq_y = sensor_EM[j]+' '+sensor_EM_u[j]
        graf_EM[i].set_ylabel(etiq_y, color='green')
    # titulos
    titulo_graf = untitulo +': '+medida_Punto[0].split('_')[0]
    titulo_graf = titulo_graf +' vs '+sensor_EM[j]
    graf_EM[0].set_title(titulo_graf)
    fig_Pt.tight_layout()
    # archivo de grafico
    arch_graf = untitulo +'_'+medida_Punto[0].split('_')[0]
    arch_graf = arch_graf +'_'+sensor_EM[j]
    plt.savefig(carpeta_rsm+'/'+arch_graf+'.png')
plt.show()

Referencia: Correlación y lectura de archivos con Python

Correlación con Python – Ejercicio Estación Meteorológica. ESTG1003 – Procesos Estocásticos

Archivos.csv con Python – Ejercicio con gráfica de temperatura y Humedad. CCPG1001 – Fundamentos de programación