<jupyter_start><jupyter_text>Tarea manejo de datos en pandas Actividades a desarrollar:1. Diga qué índices sería pertinente tener y pongalos.2. Elimine registros que tengan NA en la columna "pm2.5"3. Realice un describe de todas las variables por año. Además de realizar un gráfico como boxplot con el que pueda comparar los resultados dados.4. Realice un gráfico de dispersión de las variables "pm2.5" y "TEMP" con título, labels apropiados y color rojo para los datos. Describa: ¿Qué se puede inferir de dicho gráfico?5. Calcule la probabilidad de encontrar en la Base de datos el valor de pm2.5 encima de 1206. Para finalizar, agrupe por año el valor de la variable "pm2.5", calcule el promedio y ordene la base de datos de manera ascendente por el promedio.  **Descripción de los datos****No**: row number  **year**: year of data in this row  **month**: month of data in this row  **day**: day of data in this row  **hour**: hour of data in this row  **pm2.5**: PM2.5 concentration (ug/m^3)  **DEWP**: Dew Point (â„ƒ)  **TEMP**: Temperature (â„ƒ)  **PRES**: Pressure (hPa)  **cbwd**: Combined wind direction  **Iws**: Cumulated wind speed (m/s)  **Is**: Cumulated hours of snow  **Ir**: Cumulated hours of rain    *Carga y Exploración de los datos*<jupyter_code>import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.read_csv("PRSA_data_2010.1.1-2014.12.31.csv")
df.head()
total_datos = len(df)
print("Total de datos antes del proceso: {0}".format(total_datos))
for c in df.columns:
    print("{0}\t{1}".format(c, df[c].dtype))<jupyter_output>No	int64
year	int64
month	int64
day	int64
hour	int64
pm2.5	float64
DEWP	int64
TEMP	float64
PRES	float64
cbwd	object
Iws	float64
Is	int64
Ir	int64<jupyter_text>**Punto 1**  Se considera que el mejor índice puede ser un timestamp compuesto de los fragmentos de la fecha, pues garantiza que no habrá valores repetidos.<jupyter_code>def format_date(year, month, day, hour):
    pattern = "{year}-{month:0>2}-{day:0>2} {hour:0>2}:00"
    return pattern.format(year=year, month=month, day=day, hour=hour)
zipped_cols = zip(df.year.values,
                  df.month.values,
                  df.day.values,
                  df.hour.values)
date_format = "%Y-%m-%d %H:%M"
df["timestamp"] = [pd.to_datetime(format_date(y, m, d, h), format=date_format) for y, m, d, h in zipped_cols]
df = df.set_index("timestamp")
df.head()<jupyter_output><empty_output><jupyter_text>**Punto 2**  Se eliminan los valores nulos en la columna "pm2.5"<jupyter_code>df.dropna(axis=0, subset=['pm2.5'], inplace=True)
df.head()
datos_nona = len(df)
print('Total de datos después de quitar datos nulos en "pm2.5": {0}'.format(datos_nona))<jupyter_output>Total de datos después de quitar datos nulos en "pm2.5": 41757<jupyter_text>**Punto 3**  Se construye un dataframe de resumen (describe) de las columnas numéricas por año. Luego se hace uno para la única columna categórica.<jupyter_code>show_columns = ["pm2.5", "DEWP", "TEMP", "PRES", "Iws", "Is", "Ir"]
describe_by_year = []
for yy in df.year.unique():
    describe_yy = df[df.year==yy][show_columns].describe().transpose()
    describe_yy["year"] = yy
    describe_yy.reset_index(inplace=True)
    describe_yy.set_index(["index", "year"], inplace=True)
    describe_by_year.append(describe_yy)

df_describe = pd.concat(describe_by_year)
df_describe.sort_index()
cbwd_by_year = []
for yy in df.year.unique():
    cbwd_yy = df[df.year==yy]["cbwd"].describe().to_frame().transpose()
    cbwd_yy["year"] = yy
    cbwd_yy.reset_index(inplace=True)
    cbwd_yy.set_index(["index", "year"], inplace=True)
    cbwd_by_year.append(cbwd_yy)

df_cbwd = pd.concat(cbwd_by_year)
df_cbwd.sort_index()<jupyter_output><empty_output><jupyter_text>Se puede apreciar que el diagrama boxplot para todas las columnas juntas no es muy diciente dadas las diferencias entre sus valores. Es más claro al dividir todas las columnas entre su valor máximo, pero sigue sin ser ideal. Por lo tanto, más adelante se realizan gráficos individuales de las mismas.<jupyter_code>cols = ["pm2.5", "DEWP", "TEMP", "PRES", "Iws", "Is", "Ir"]
col_min = {c:min(df[c]) for c in cols}
col_max = {c:max(df[c]) for c in cols}
df_scaled = {c:(df[c].values - col_min[c])/(col_max[c] - col_min[c]) for c in cols}
df_scaled = pd.DataFrame(df_scaled)
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(15,5))
ax[0].set_xlabel("Column")
ax[1].set_xlabel("Column")
ax[0].set_ylabel("Values")
ax[1].set_ylabel("Linear-Scaled Values")
ax[0].boxplot(df[cols].values, labels=cols, showfliers=False)
ax[1].boxplot(df_scaled[cols].values, labels=cols, showfliers=True)
plt.show()
fig, ax = plt.subplots(nrows=2, ncols=4, figsize=(15, 10))
ax[0,0].boxplot(df["pm2.5"].values, labels=["PM 2.5 - no outliers"], showfliers=False)
ax[0,1].boxplot(df["pm2.5"].values, labels=["PM 2.5 - with outliers"], showfliers=True)
ax[0,2].boxplot(df["DEWP"].values, labels=["Dew Point"], showfliers=False)
ax[0,3].boxplot(df["TEMP"].values, labels=["Temperature C"], showfliers=False)
ax[1,0].boxplot(df["PRES"].values, labels=["Atm. Pressure"], showfliers=False)
ax[1,1].boxplot(df["Iws"].values, labels=["Iws"], showfliers=False)
ax[1,2].boxplot(df["Is"].values, labels=["Is"], showfliers=True)
ax[1,3].boxplot(df["Ir"].values, labels=["Ir"], showfliers=True)
plt.show()<jupyter_output><empty_output><jupyter_text>**Punto 4**  Se construye un diagrama de dispersión de la concentración de material particulado PM2.5 contra la temperatura. Se aprecia una tendencia que pareciera ser normal (gaussiana), con tendencia a mostrar su pico cerca de la media de temperatura (12 C, aprox.).<jupyter_code>print("Temperatura media:", np.mean(df["TEMP"].values))
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(10, 10))
ax.scatter(x=df["TEMP"].values, y=df["pm2.5"].values, color="red")
ax.set_title("PM2.5 concentration vs. Temperature [C]")
ax.set_ylabel("PM 2.5 [um/m^3]")
ax.set_xlabel("Temperature [C]")
plt.show()<jupyter_output><empty_output><jupyter_text>**Punto 5**  Se calcula la probabilidad de encontrar un valor mayor a 120 en el campo "pm2.5".<jupyter_code>prob_total = len(df[df["pm2.5"]>120])/total_datos
prob_nona = len(df[df["pm2.5"]>120])/datos_nona<jupyter_output><empty_output><jupyter_text>Probabilidad de encontrar un dato mayor a 120 en la columna pm2.5 en el dataset **original**:<jupyter_code>print("P(pm2.5 > 120 um/m^3): {0:.2%}".format(prob_total))<jupyter_output>P(pm2.5 > 120 um/m^3): 28.48%<jupyter_text>Probabilidad de encontrar un dato mayor a 120 en la columna pm2.5 en el dataset **tras remover datos nulos**:<jupyter_code>print("P(pm2.5 > 120 um/m^3 AND pm2.5 is not None): {0:.2%}".format(prob_nona))<jupyter_output>P(pm2.5 > 120 um/m^3 AND pm2.5 is not None): 29.89%<jupyter_text>**Punto 6**  Se calcula el valor promedio por año para la variable "pm2.5" y se ordena de forma ascendente por valor.<jupyter_code>promedio_yy = df.groupby("year")["pm2.5"].mean().sort_values(ascending=True)
promedio_yy.to_frame()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15112953960537603, 'fraction_numerical': 0.03217043179868459, 'mean_word_length': 5.661904761904762, 'pattern_counts': {'":': 2, '<': 37, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '44443', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 2797, 'n_tokens_neox': 2706, 'n_words': 705, 'path': 'tarea_pandas/tarea_pandas.ipynb', 'repo_name': 'crcollazosg/diplomado_ml_un', 'size': '6994'}