QA: AEMET dataset 🌥️
INESDATA-MOV
Análisis de calidad¶
Este cuaderno analiza la calidad del dataset proveniente de la fuente de datos de la Agencia Estatal de Meteorología (AEMET). La calidad del mismo se validará teniendo en cuenta los siguientes aspectos:
- Análisis del dataset
- Análisis de las variables
- Conversiones de tipos de datos
La calidad del dato se refiere a la medida en que los datos son adecuados para su uso, por lo que es esencial para garantizar la confiabilidad y utilidad de los datos en diversas aplicaciones y contextos. Así, en este notebook se evaluarán también las cinco dimensiones de la calidad del dato:
- Unicidad: Ausencia de duplicados o registros repetidos en un conjunto de datos. Los datos son únicos cuando cada registro o entidad en el conjunto de datos es único y no hay duplicados presentes.
- Exactitud: Los datos exactos son libres de errores y representan con precisión la realidad que están destinados a describir. Esto implica que los datos deben ser correctos y confiables para su uso en análisis y toma de decisiones.
- Completitud: Los datos completos contienen toda la información necesaria para el análisis y no tienen valores faltantes o nulos que puedan afectar la interpretación o validez de los resultados.
- Consistencia: Los datos consistentes mantienen el mismo formato, estructura y significado en todas las instancias, lo que facilita su comparación y análisis sin ambigüedad.
- Validez: Medida en que los datos son precisos y representan con exactitud la realidad que están destinados a describir.
Nota
Este dataset ha sido creado ejecutando el comando create
del paquete de Python inesdata_mov_datasets
.
Para poder ejecutar este comando es necesario haber ejecutado antes el comando extract
, que realiza la extracción de datos de la API de la AEMET y los almacena en Minio. El comando create
se encargaría de descargar dichos datos y unirlos todos en un único dataset.
import os
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings("ignore")
from ydata_profiling import ProfileReport
ROOT_PATH = os.path.dirname(os.path.dirname(os.path.abspath(os.getcwd())))
DATA_PATH = os.path.join(ROOT_PATH, "data", "processed")
AEMET_DATA_PATH = os.path.join(DATA_PATH, "aemet")
Cada fila de este dataset representa la meteorología de Madrid para una determinada fecha y hora concretos.
-
Vamos a analizar la calidad del dataset generado para los días comprendidos entre 02/03/2024 - 31/03/2024 que son los días de los que disponemos información actualmente.
#####################################################################
# Creacción del dataset completo con toda la información disponible #
#####################################################################
# Directorio con los CSV
directory = AEMET_DATA_PATH
aemet_data = []
for root, directories, files in os.walk(directory):
for filename in files:
if filename.endswith('.csv'):
filepath = os.path.join(root, filename)
aemet_data.append(pd.read_csv(filepath))
aemet_dataset = pd.concat(aemet_data, ignore_index=True)
QA checks ✅¶
Análisis del dataset¶
# Visualización del dataset
aemet_dataset.head()
estadoCielo_value | estadoCielo_descripcion | precipitacion_value | probPrecipitacion_value | probTormenta_value | nieve_value | probNieve_value | temperatura_value | sensTermica_value | humedadRelativa_value | direccion | velocidad | vientoAndRachaMax_value | datetime | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 12n | Poco nuboso | 0 | NaN | NaN | 0 | NaN | 8.0 | 5.0 | 77.0 | ['SO'] | ['16'] | NaN | 2024-03-02 00:00:00 |
1 | 12n | Poco nuboso | 0 | NaN | NaN | 0 | NaN | 8.0 | 5.0 | 77.0 | NaN | NaN | 27.0 | 2024-03-02 00:00:00 |
2 | 15n | Muy nuboso | 0 | NaN | NaN | 0 | NaN | 8.0 | 5.0 | 80.0 | ['O'] | ['17'] | NaN | 2024-03-02 01:00:00 |
3 | 15n | Muy nuboso | 0 | NaN | NaN | 0 | NaN | 8.0 | 5.0 | 80.0 | NaN | NaN | 27.0 | 2024-03-02 01:00:00 |
4 | NaN | NaN | NaN | 0.0 | 0.0 | NaN | 0.0 | NaN | NaN | NaN | NaN | NaN | NaN | 2024-03-02 01:07:00 |
aemet_dataset[aemet_dataset["datetime"]=="2024-03-02 00:00:00"]
estadoCielo_value | estadoCielo_descripcion | precipitacion_value | probPrecipitacion_value | probTormenta_value | nieve_value | probNieve_value | temperatura_value | sensTermica_value | humedadRelativa_value | direccion | velocidad | vientoAndRachaMax_value | datetime | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 12n | Poco nuboso | 0 | NaN | NaN | 0 | NaN | 8.0 | 5.0 | 77.0 | ['SO'] | ['16'] | NaN | 2024-03-02 00:00:00 |
1 | 12n | Poco nuboso | 0 | NaN | NaN | 0 | NaN | 8.0 | 5.0 | 77.0 | NaN | NaN | 27.0 | 2024-03-02 00:00:00 |
1626 | 12n | Poco nuboso | 0.0 | NaN | NaN | 0 | NaN | 8.0 | 5.0 | 77.0 | ['SO'] | ['16'] | NaN | 2024-03-02 00:00:00 |
1627 | 12n | Poco nuboso | 0.0 | NaN | NaN | 0 | NaN | 8.0 | 5.0 | 77.0 | NaN | NaN | 27.0 | 2024-03-02 00:00:00 |
aemet_dataset.groupby(["datetime"])["datetime"].count().sort_values(ascending=False)
datetime 2024-03-02 00:00:00 4 2024-03-21 13:00:00 4 2024-03-21 05:00:00 4 2024-03-21 06:00:00 4 2024-03-21 07:00:00 4 .. 2024-03-07 13:19:00 2 2024-03-19 07:13:00 2 2024-03-27 19:01:00 2 2024-03-05 07:13:00 2 2024-03-18 13:19:00 2 Name: datetime, Length: 773, dtype: int64
aemet_dataset.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 2848 entries, 0 to 2847 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 estadoCielo_value 2624 non-null object 1 estadoCielo_descripcion 2624 non-null object 2 precipitacion_value 2624 non-null object 3 probPrecipitacion_value 224 non-null float64 4 probTormenta_value 224 non-null float64 5 nieve_value 2624 non-null object 6 probNieve_value 224 non-null float64 7 temperatura_value 2604 non-null float64 8 sensTermica_value 2604 non-null float64 9 humedadRelativa_value 2604 non-null float64 10 direccion 1302 non-null object 11 velocidad 1302 non-null object 12 vientoAndRachaMax_value 1302 non-null float64 13 datetime 2848 non-null object dtypes: float64(7), object(7) memory usage: 311.6+ KB
aemet_dataset["precipitacion_value"].unique()
array(['0', nan, '0.1', '0.6', '6', '0.2', '1', '0.5', '4', '0.9', '0.8', '0.7', 'Ip', '0.3', '3', '2', '0.4', 0.0, 0.1, 0.6, 6.0, 0.2, 1.0, 0.5, 4.0, 0.9, 3.0, 2.0, 0.4, 0.3, 0.7, 0.8], dtype=object)
aemet_dataset["nieve_value"].unique()
array(['0', nan, 'Ip', 0.0], dtype=object)
aemet_dataset = aemet_dataset.replace({'precipitacion_value': {"Ip":0.0}, 'nieve_value': {"Ip":0.0}})
aemet_dataset["precipitacion_value"].unique()
array(['0', nan, '0.1', '0.6', '6', '0.2', '1', '0.5', '4', '0.9', '0.8', '0.7', 0.0, '0.3', '3', '2', '0.4', 0.1, 0.6, 6.0, 0.2, 1.0, 0.5, 4.0, 0.9, 3.0, 2.0, 0.4, 0.3, 0.7, 0.8], dtype=object)
aemet_dataset["precipitacion_value"].unique()
array(['0', nan, '0.1', '0.6', '6', '0.2', '1', '0.5', '4', '0.9', '0.8', '0.7', 0.0, '0.3', '3', '2', '0.4', 0.1, 0.6, 6.0, 0.2, 1.0, 0.5, 4.0, 0.9, 3.0, 2.0, 0.4, 0.3, 0.7, 0.8], dtype=object)
aemet_dataset = aemet_dataset.astype({'estadoCielo_value': 'str', 'estadoCielo_descripcion':'str',\
'precipitacion_value': 'float64', 'probPrecipitacion_value': 'float64',\
'probTormenta_value': 'float64', 'nieve_value': 'float64',\
'probNieve_value': 'float64', 'temperatura_value': 'float64',\
'sensTermica_value': 'float64', 'humedadRelativa_value': 'float64',\
'vientoAndRachaMax_value': 'float64'
})
aemet_dataset.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 2848 entries, 0 to 2847 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 estadoCielo_value 2848 non-null object 1 estadoCielo_descripcion 2848 non-null object 2 precipitacion_value 2624 non-null float64 3 probPrecipitacion_value 224 non-null float64 4 probTormenta_value 224 non-null float64 5 nieve_value 2624 non-null float64 6 probNieve_value 224 non-null float64 7 temperatura_value 2604 non-null float64 8 sensTermica_value 2604 non-null float64 9 humedadRelativa_value 2604 non-null float64 10 direccion 1302 non-null object 11 velocidad 1302 non-null object 12 vientoAndRachaMax_value 1302 non-null float64 13 datetime 2848 non-null object dtypes: float64(9), object(5) memory usage: 311.6+ KB
aemet_dataset = aemet_dataset.drop_duplicates()
aemet_dataset.groupby(["datetime"])["datetime"].count().sort_values(ascending=False)
datetime 2024-03-02 00:00:00 2 2024-03-21 13:00:00 2 2024-03-21 05:00:00 2 2024-03-21 06:00:00 2 2024-03-21 07:00:00 2 .. 2024-03-07 13:19:00 1 2024-03-19 07:13:00 1 2024-03-27 19:01:00 1 2024-03-05 07:13:00 1 2024-03-18 13:19:00 1 Name: datetime, Length: 773, dtype: int64
aemet_dataset[aemet_dataset["datetime"]=="2024-03-02 00:00:00"]
estadoCielo_value | estadoCielo_descripcion | precipitacion_value | probPrecipitacion_value | probTormenta_value | nieve_value | probNieve_value | temperatura_value | sensTermica_value | humedadRelativa_value | direccion | velocidad | vientoAndRachaMax_value | datetime | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 12n | Poco nuboso | 0.0 | NaN | NaN | 0.0 | NaN | 8.0 | 5.0 | 77.0 | ['SO'] | ['16'] | NaN | 2024-03-02 00:00:00 |
1 | 12n | Poco nuboso | 0.0 | NaN | NaN | 0.0 | NaN | 8.0 | 5.0 | 77.0 | NaN | NaN | 27.0 | 2024-03-02 00:00:00 |
aemet_reduced = aemet_dataset.groupby(["datetime"])[['direccion','velocidad','vientoAndRachaMax_value']].sum()
aemet_dataset = aemet_dataset.drop(columns=["direccion", "velocidad", "vientoAndRachaMax_value"])
aemet_dataset = aemet_dataset.merge(aemet_reduced, how="inner", on= "datetime").drop_duplicates()
aemet_dataset.groupby(["datetime"])["datetime"].count().sort_values(ascending=False)
datetime 2024-03-02 00:00:00 1 2024-03-21 07:00:00 1 2024-03-22 06:00:00 1 2024-03-22 07:00:00 1 2024-03-22 07:13:00 1 .. 2024-03-13 07:00:00 1 2024-03-13 07:13:00 1 2024-03-13 08:00:00 1 2024-03-13 09:00:00 1 2024-03-31 23:00:00 1 Name: datetime, Length: 773, dtype: int64
aemet_dataset_test = aemet_dataset.copy()
aemet_dataset_test["datetime"] = pd.to_datetime(aemet_dataset_test["datetime"])
aemet_dataset_test["day"] = aemet_dataset_test["datetime"].dt.day
aemet_dataset_test["month"] = aemet_dataset_test["datetime"].dt.month
aemet_dataset_test["year"] = aemet_dataset_test["datetime"].dt.year
aemet_dataset_test["hour"] = aemet_dataset_test["datetime"].dt.hour
aemet_dataset_test["minute"] = aemet_dataset_test["datetime"].dt.minute
aemet_dataset_test[aemet_dataset_test["minute"]==0].groupby(["month", "day"])[["estadoCielo_value"]].count()
estadoCielo_value | ||
---|---|---|
month | day | |
3 | 2 | 24 |
3 | 24 | |
4 | 24 | |
5 | 24 | |
6 | 24 | |
7 | 24 | |
8 | 24 | |
11 | 24 | |
12 | 24 | |
13 | 24 | |
14 | 24 | |
15 | 24 | |
16 | 24 | |
17 | 24 | |
18 | 24 | |
19 | 24 | |
20 | 24 | |
21 | 24 | |
22 | 23 | |
23 | 23 | |
24 | 23 | |
25 | 23 | |
26 | 23 | |
27 | 23 | |
28 | 23 | |
29 | 23 | |
30 | 23 | |
31 | 22 |
aemet_dataset.reset_index(drop=True, inplace=True)
Análisis de las variables y conversiones de tipos¶
aemet_dataset.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 773 entries, 0 to 772 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 estadoCielo_value 773 non-null object 1 estadoCielo_descripcion 773 non-null object 2 precipitacion_value 661 non-null float64 3 probPrecipitacion_value 112 non-null float64 4 probTormenta_value 112 non-null float64 5 nieve_value 661 non-null float64 6 probNieve_value 112 non-null float64 7 temperatura_value 651 non-null float64 8 sensTermica_value 651 non-null float64 9 humedadRelativa_value 651 non-null float64 10 datetime 773 non-null object 11 direccion 773 non-null object 12 velocidad 773 non-null object 13 vientoAndRachaMax_value 773 non-null float64 dtypes: float64(9), object(5) memory usage: 84.7+ KB
Estado cielo¶
aemet_dataset[["estadoCielo_value", "estadoCielo_descripcion"]].groupby(["estadoCielo_descripcion", "estadoCielo_value"]).count()
estadoCielo_descripcion | estadoCielo_value |
---|---|
Bruma | 82 |
82n | |
Cubierto | 16 |
16n | |
Cubierto con lluvia | 26 |
26n | |
Cubierto con lluvia escasa | 46 |
46n | |
Cubierto con nieve | 36 |
Cubierto con tormenta | 54 |
54n | |
Cubierto con tormenta y lluvia escasa | 64 |
64n | |
Despejado | 11 |
11n | |
Intervalos nubosos | 13 |
Intervalos nubosos con lluvia escasa | 43 |
43n | |
Muy nuboso | 15 |
15n | |
Muy nuboso con lluvia escasa | 45 |
45n | |
Muy nuboso con tormenta y lluvia escasa | 63n |
Niebla | 81 |
Nubes altas | 17 |
17n | |
Nuboso | 14 |
14n | |
Nuboso con lluvia escasa | 44 |
Nuboso con tormenta y lluvia escasa | 62 |
Poco nuboso | 12 |
12n | |
nan | nan |
# Cambiamos los valores 12n, 17n, etc. por 12, 17, etc. ya que representan el
# mismo valor de estadoCielo
aemet_dataset["estadoCielo_value"] = aemet_dataset["estadoCielo_value"].replace(to_replace=r'(\d+)n', value=r'\1', regex=True).replace('nan', np.nan)
aemet_dataset[["estadoCielo_value", "estadoCielo_descripcion"]].groupby(["estadoCielo_descripcion", "estadoCielo_value"]).count()
estadoCielo_descripcion | estadoCielo_value |
---|---|
Bruma | 82 |
Cubierto | 16 |
Cubierto con lluvia | 26 |
Cubierto con lluvia escasa | 46 |
Cubierto con nieve | 36 |
Cubierto con tormenta | 54 |
Cubierto con tormenta y lluvia escasa | 64 |
Despejado | 11 |
Intervalos nubosos | 13 |
Intervalos nubosos con lluvia escasa | 43 |
Muy nuboso | 15 |
Muy nuboso con lluvia escasa | 45 |
Muy nuboso con tormenta y lluvia escasa | 63 |
Niebla | 81 |
Nubes altas | 17 |
Nuboso | 14 |
Nuboso con lluvia escasa | 44 |
Nuboso con tormenta y lluvia escasa | 62 |
Poco nuboso | 12 |
# Eliminamos la columna estadoCielo_descripcion
aemet_dataset.drop(columns='estadoCielo_descripcion', inplace=True)
# Cambiamos el tipo de la variable estadoCielo_value a numérico y
# cambiamos el nombre de esta columna por estado_cielo
aemet_dataset['estadoCielo_value'] = pd.to_numeric(aemet_dataset['estadoCielo_value'], errors='coerce')
aemet_dataset.rename(columns={'estadoCielo_value': 'estado_cielo'}, inplace=True)
aemet_dataset["estado_cielo"].value_counts(dropna=False)
estado_cielo 17.0 169 11.0 163 NaN 112 16.0 105 12.0 61 46.0 47 64.0 47 15.0 27 43.0 15 14.0 10 36.0 3 54.0 3 45.0 2 26.0 2 82.0 2 63.0 1 44.0 1 81.0 1 62.0 1 13.0 1 Name: count, dtype: int64
Precipitación¶
aemet_dataset.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 773 entries, 0 to 772 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 estado_cielo 661 non-null float64 1 precipitacion_value 661 non-null float64 2 probPrecipitacion_value 112 non-null float64 3 probTormenta_value 112 non-null float64 4 nieve_value 661 non-null float64 5 probNieve_value 112 non-null float64 6 temperatura_value 651 non-null float64 7 sensTermica_value 651 non-null float64 8 humedadRelativa_value 651 non-null float64 9 datetime 773 non-null object 10 direccion 773 non-null object 11 velocidad 773 non-null object 12 vientoAndRachaMax_value 773 non-null float64 dtypes: float64(10), object(3) memory usage: 78.6+ KB
aemet_dataset[~aemet_dataset["probPrecipitacion_value"].isnull()][["datetime", "probPrecipitacion_value"]].head()
datetime | probPrecipitacion_value | |
---|---|---|
2 | 2024-03-02 01:07:00 | 0.0 |
9 | 2024-03-02 07:13:00 | 100.0 |
16 | 2024-03-02 13:19:00 | 100.0 |
23 | 2024-03-02 19:01:00 | 70.0 |
30 | 2024-03-03 01:07:00 | 0.0 |
aemet_dataset_prob = aemet_dataset.copy()
aemet_dataset_prob["datetime"] = pd.to_datetime(aemet_dataset_prob["datetime"])
aemet_dataset_prob["day"] = aemet_dataset_prob["datetime"].dt.day
aemet_dataset_prob["month"] = aemet_dataset_prob["datetime"].dt.month
aemet_dataset_prob["year"] = aemet_dataset_prob["datetime"].dt.year
aemet_dataset_prob["hour"] = aemet_dataset_prob["datetime"].dt.hour
aemet_dataset_prob["minute"] = aemet_dataset_prob["datetime"].dt.minute
aemet_dataset_prob["second"] = aemet_dataset_prob["datetime"].dt.second
aemet_dataset_prob = aemet_dataset_prob[["day", "month", "hour", "minute", "second", "probPrecipitacion_value", "probTormenta_value", "probNieve_value"]]
aemet_dataset_prob[0:10]
day | month | hour | minute | second | probPrecipitacion_value | probTormenta_value | probNieve_value | |
---|---|---|---|---|---|---|---|---|
0 | 2 | 3 | 0 | 0 | 0 | NaN | NaN | NaN |
1 | 2 | 3 | 1 | 0 | 0 | NaN | NaN | NaN |
2 | 2 | 3 | 1 | 7 | 0 | 0.0 | 0.0 | 0.0 |
3 | 2 | 3 | 2 | 0 | 0 | NaN | NaN | NaN |
4 | 2 | 3 | 3 | 0 | 0 | NaN | NaN | NaN |
5 | 2 | 3 | 4 | 0 | 0 | NaN | NaN | NaN |
6 | 2 | 3 | 5 | 0 | 0 | NaN | NaN | NaN |
7 | 2 | 3 | 6 | 0 | 0 | NaN | NaN | NaN |
8 | 2 | 3 | 7 | 0 | 0 | NaN | NaN | NaN |
9 | 2 | 3 | 7 | 13 | 0 | 100.0 | 25.0 | 0.0 |
aemet_dataset_prob[0:10].fillna(method="ffill")
day | month | hour | minute | second | probPrecipitacion_value | probTormenta_value | probNieve_value | |
---|---|---|---|---|---|---|---|---|
0 | 2 | 3 | 0 | 0 | 0 | NaN | NaN | NaN |
1 | 2 | 3 | 1 | 0 | 0 | NaN | NaN | NaN |
2 | 2 | 3 | 1 | 7 | 0 | 0.0 | 0.0 | 0.0 |
3 | 2 | 3 | 2 | 0 | 0 | 0.0 | 0.0 | 0.0 |
4 | 2 | 3 | 3 | 0 | 0 | 0.0 | 0.0 | 0.0 |
5 | 2 | 3 | 4 | 0 | 0 | 0.0 | 0.0 | 0.0 |
6 | 2 | 3 | 5 | 0 | 0 | 0.0 | 0.0 | 0.0 |
7 | 2 | 3 | 6 | 0 | 0 | 0.0 | 0.0 | 0.0 |
8 | 2 | 3 | 7 | 0 | 0 | 0.0 | 0.0 | 0.0 |
9 | 2 | 3 | 7 | 13 | 0 | 100.0 | 25.0 | 0.0 |
aemet_dataset["datetime"] = pd.to_datetime(aemet_dataset["datetime"])
aemet_dataset["day"] = aemet_dataset["datetime"].dt.day
aemet_dataset["month"] = aemet_dataset["datetime"].dt.month
aemet_dataset["year"] = aemet_dataset["datetime"].dt.year
aemet_dataset["hour"] = aemet_dataset["datetime"].dt.hour
aemet_dataset["minute"] = aemet_dataset["datetime"].dt.minute
aemet_dataset["second"] = aemet_dataset["datetime"].dt.second
aemet_dataset.drop(columns=["datetime"], inplace=True)
aemet_dataset.fillna(method="ffill", inplace=True)
aemet_dataset = aemet_dataset[aemet_dataset.minute==0]
aemet_dataset.reset_index(drop=True, inplace=True)
aemet_dataset.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 661 entries, 0 to 660 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 estado_cielo 661 non-null float64 1 precipitacion_value 661 non-null float64 2 probPrecipitacion_value 659 non-null float64 3 probTormenta_value 659 non-null float64 4 nieve_value 661 non-null float64 5 probNieve_value 659 non-null float64 6 temperatura_value 661 non-null float64 7 sensTermica_value 661 non-null float64 8 humedadRelativa_value 661 non-null float64 9 direccion 661 non-null object 10 velocidad 661 non-null object 11 vientoAndRachaMax_value 661 non-null float64 12 day 661 non-null int32 13 month 661 non-null int32 14 year 661 non-null int32 15 hour 661 non-null int32 16 minute 661 non-null int32 17 second 661 non-null int32 dtypes: float64(10), int32(6), object(2) memory usage: 77.6+ KB
Nieve¶
Dirección¶
La variable direccion representa los valores de norte, sur, este, oeste. Como vienen en una lista, los sacamos y los convertimos a categorías.
aemet_dataset["direccion"].value_counts()
direccion ['SO'] 143 ['NE'] 135 ['O'] 117 ['S'] 104 ['SE'] 54 ['E'] 48 ['NO'] 37 ['N'] 13 0 10 Name: count, dtype: int64
aemet_dataset["direccion"] = aemet_dataset["direccion"].str.replace("['", "").str.replace("']", "").astype('category')
aemet_dataset["direccion"].unique()
['SO', 'O', 'NO', 'NE', 'N', 'S', 'SE', 'E', NaN] Categories (8, object): ['E', 'N', 'NE', 'NO', 'O', 'S', 'SE', 'SO']
Velocidad¶
Los valores de la variable velocidad vienen en una lista, los sacamos y los convertimos a float.
aemet_dataset['velocidad'].value_counts().head()
velocidad ['10'] 54 ['8'] 47 ['9'] 46 ['7'] 39 ['6'] 34 Name: count, dtype: int64
aemet_dataset["velocidad"] = aemet_dataset["velocidad"].str.replace("['", "").str.replace("']", "").astype(float)
aemet_dataset["velocidad"].value_counts().head()
velocidad 10.0 54 8.0 47 9.0 46 7.0 39 6.0 34 Name: count, dtype: int64
aemet_dataset[0:20]
estado_cielo | precipitacion_value | probPrecipitacion_value | probTormenta_value | nieve_value | probNieve_value | temperatura_value | sensTermica_value | humedadRelativa_value | direccion | velocidad | vientoAndRachaMax_value | day | month | year | hour | minute | second | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 12.0 | 0.0 | NaN | NaN | 0.0 | NaN | 8.0 | 5.0 | 77.0 | SO | 16.0 | 27.0 | 2 | 3 | 2024 | 0 | 0 | 0 |
1 | 15.0 | 0.0 | NaN | NaN | 0.0 | NaN | 8.0 | 5.0 | 80.0 | O | 17.0 | 27.0 | 2 | 3 | 2024 | 1 | 0 | 0 |
2 | 15.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 8.0 | 5.0 | 82.0 | O | 17.0 | 33.0 | 2 | 3 | 2024 | 2 | 0 | 0 |
3 | 16.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 8.0 | 5.0 | 84.0 | SO | 20.0 | 40.0 | 2 | 3 | 2024 | 3 | 0 | 0 |
4 | 16.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 8.0 | 4.0 | 86.0 | O | 25.0 | 35.0 | 2 | 3 | 2024 | 4 | 0 | 0 |
5 | 16.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 8.0 | 5.0 | 84.0 | SO | 21.0 | 37.0 | 2 | 3 | 2024 | 5 | 0 | 0 |
6 | 16.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 8.0 | 5.0 | 86.0 | SO | 23.0 | 44.0 | 2 | 3 | 2024 | 6 | 0 | 0 |
7 | 16.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 8.0 | 4.0 | 82.0 | SO | 27.0 | 51.0 | 2 | 3 | 2024 | 7 | 0 | 0 |
8 | 16.0 | 0.0 | 100.0 | 25.0 | 0.0 | 0.0 | 8.0 | 4.0 | 81.0 | SO | 32.0 | 47.0 | 2 | 3 | 2024 | 8 | 0 | 0 |
9 | 46.0 | 0.1 | 100.0 | 25.0 | 0.0 | 0.0 | 8.0 | 4.0 | 80.0 | SO | 28.0 | 47.0 | 2 | 3 | 2024 | 9 | 0 | 0 |
10 | 16.0 | 0.0 | 100.0 | 25.0 | 0.0 | 0.0 | 8.0 | 4.0 | 80.0 | SO | 30.0 | 50.0 | 2 | 3 | 2024 | 10 | 0 | 0 |
11 | 16.0 | 0.0 | 100.0 | 25.0 | 0.0 | 0.0 | 8.0 | 4.0 | 78.0 | SO | 29.0 | 51.0 | 2 | 3 | 2024 | 11 | 0 | 0 |
12 | 16.0 | 0.0 | 100.0 | 25.0 | 0.0 | 0.0 | 8.0 | 4.0 | 73.0 | SO | 31.0 | 57.0 | 2 | 3 | 2024 | 12 | 0 | 0 |
13 | 64.0 | 0.1 | 100.0 | 25.0 | 0.0 | 0.0 | 8.0 | 4.0 | 75.0 | SO | 35.0 | 58.0 | 2 | 3 | 2024 | 13 | 0 | 0 |
14 | 64.0 | 0.1 | 100.0 | 80.0 | 0.0 | 0.0 | 9.0 | 5.0 | 75.0 | SO | 35.0 | 62.0 | 2 | 3 | 2024 | 14 | 0 | 0 |
15 | 16.0 | 0.0 | 100.0 | 80.0 | 0.0 | 0.0 | 9.0 | 5.0 | 79.0 | SO | 38.0 | 62.0 | 2 | 3 | 2024 | 15 | 0 | 0 |
16 | 64.0 | 0.1 | 100.0 | 80.0 | 0.0 | 0.0 | 9.0 | 5.0 | 79.0 | SO | 38.0 | 61.0 | 2 | 3 | 2024 | 16 | 0 | 0 |
17 | 64.0 | 0.6 | 100.0 | 80.0 | 0.0 | 0.0 | 8.0 | 3.0 | 86.0 | SO | 39.0 | 72.0 | 2 | 3 | 2024 | 17 | 0 | 0 |
18 | 36.0 | 6.0 | 100.0 | 80.0 | 0.0 | 0.0 | 8.0 | 3.0 | 91.0 | SO | 45.0 | 28.0 | 2 | 3 | 2024 | 18 | 0 | 0 |
19 | 46.0 | 0.2 | 100.0 | 80.0 | 0.0 | 0.0 | 7.0 | 5.0 | 71.0 | O | 11.0 | 19.0 | 2 | 3 | 2024 | 19 | 0 | 0 |
aemet_dataset.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 661 entries, 0 to 660 Data columns (total 18 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 estado_cielo 661 non-null float64 1 precipitacion_value 661 non-null float64 2 probPrecipitacion_value 659 non-null float64 3 probTormenta_value 659 non-null float64 4 nieve_value 661 non-null float64 5 probNieve_value 659 non-null float64 6 temperatura_value 661 non-null float64 7 sensTermica_value 661 non-null float64 8 humedadRelativa_value 661 non-null float64 9 direccion 651 non-null category 10 velocidad 651 non-null float64 11 vientoAndRachaMax_value 661 non-null float64 12 day 661 non-null int32 13 month 661 non-null int32 14 year 661 non-null int32 15 hour 661 non-null int32 16 minute 661 non-null int32 17 second 661 non-null int32 dtypes: category(1), float64(11), int32(6) memory usage: 73.4 KB
PROFILING 📑¶
profile = ProfileReport(
aemet_dataset,
title="🌥️ AEMET QA",
dataset={
"description": "AEMET - Estado de la meteorología",
"url": "https://opendata.aemet.es/dist/index.html",
},
variables={
"descriptions": {
"day": "Fecha (día) de la petición a la API",
"month": "Fecha (mes) de la petición a la API",
"year": "Fecha (año) de la petición a la API",
"hour": "Fecha (hora) de la petición a la API",
"minute": "Fecha (minute) de la petición a la API",
"second": "Fecha (second) de la petición a la API",
"estado_cielo": "Estado del cielo",
"precipitacion_value": "Precipitación",
"probPrecipitacion_value": "Probabilidad de precipitación",
"probTormenta_value": "Probabilidad de tormenta",
"nieve_value": "Nieve",
"probNieve_value": "Probabilidad de nieve",
"temperatura_value": "Temperatura",
"sensTermica_value": "Sensación térmica",
"humedadRelativa_value": "Humedad relativa",
"direccion": "Dirección del viento",
"velocidad": "Velocidad del viento",
"vientoAndRachaMax_value": "Viento racha máxima",
}
},
interactions=None,
explorative=True,
dark_mode=True,
)
profile.to_file(os.path.join(ROOT_PATH, "docs", "qa", "aemet_report.html"))
# profile.to_notebook_iframe()