Partículas de Ozono en la Ciudad de México

Datos Misteriosos

Juan-Campos A., Martínez-Rivas L., Sánchez-Juárez P.

Facultad de Ciencias, Universidad Nacional Autónoma de México, Ciudad Universitaria, Cto. Exterior s/n, Coyoacán, CDMX, México C.P. 04510

Introducción

El presente proyecto muestra cómo realizar el análisis de una base de datos desde cero utilizando la biblioteca Pandas en Python. El análisis de datos es una herramienta escencial en el ámbito científico y aprender a utilizar programas que faciliten esta tarea es sumamente útil, además de que amplia la perspectiva de la información que obtenemos por métodos sencillos.

Pandas y los Metadatos

Para iniciar nuestro análisis de datos importamos la biblioteca pandas.

In [29]:
import pandas as pd

Abrimos un archivo de texto usando el método "pd.read_csv".

In [30]:
data = pd.read_csv('archivo02.csv', sep=",", header=4 , na_values=-99)

Para saber las generalidades de "data" utilizamos el comando data.describe

In [19]:
data.describe()
Out[19]:
AJU MGH
count 4655.000000 8357.000000
mean 36.604726 28.178533
std 26.022067 25.638901
min 0.000000 0.000000
25% 16.000000 7.000000
50% 31.000000 21.000000
75% 53.000000 43.000000
max 143.000000 131.000000

Tabla 1. Descripción general de los datos de monitoreo atmosférico.

Si entramos al archivo de excel podemos ver que nuestros datos provienen de la red automática de monitoreo atmosférico de la ciudad de México. Al ejecutar la función data.describe() aparece una tabla. El archivo tiene 4 lineas de encabezado y un valor nulo de -99. Hay dos columnas AJU y MGH, en el documento de excel nos dicen que estás dos son estaciones de monitoreo de O3.

La Tabla 1 nos muestra el conteo de partículas de ozono por estación de monitoreo, la desviación estandar, promedio, valores máximos y mínimos, y diversos porcentajes de las mediciones obtenidas.

Las mediciones de Ozono están reportadas en partes por billon (ppb). Estas unidades no corresponden al sistema internacional de unidades. Aun cuando el uso de términos tales como partes por millón (ppm), partes por billón (ppb) y partes por trillón (ppt) tienen cierto uso en el lenguaje de la composición química, estos términos no se han definido formalmente y no existe aún un consenso en cuanto a su uso (Gutiérrez,et.al,2010).

La mejor forma para analizar datos de forma simple es visualmente. Para fácilitar la comprensión de los datos utilizamos varios tipos de gráficas en las cuales fuimos mejorando la presentación de nuestros datos.

Gráficas

In [2]:
import pandas as pd

import matplotlib.pyplot as plt 
data=pd.read_csv('archivo02.csv', sep=",", header=4 , na_values=-99)
fig,ax = plt.subplots(1,1)

fecha=pd.to_datetime(data['FECHA'])
ax.plot(fecha,data["AJU"],"o",label= "AJU", color="purple")
ax.plot(fecha,data["MGH"],"o",label= "MGH", color="blue")

ax.set_ylabel("O3(ppb)")
ax.set_title("Fecha")
ax.set_xlim(fecha[0],fecha[998])

ax.legend()
fig.autofmt_xdate()
print("Gráfica 1. Mediciones de partículas de Ozono en el año 2019")
Gráfica 1. Mediciones de partículas de Ozono en el año 2019
In [4]:
import pandas as pd

import matplotlib.pyplot as plt 
data=pd.read_csv('archivo02.csv', sep=",", header=4 , na_values=-99)
fig,ax = plt.subplots(1,1)
ax.plot(pd.to_datetime(data['FECHA'][1710:1760]),data["AJU"][1710:1760],"o",label= "AJU", color="purple")
ax.plot(pd.to_datetime(data['FECHA'][1710:1760]),data["MGH"][1710:1760],"o",label= "MGH", color="red")

ax.set_ylabel("O3(ppb)")
ax.set_title("Fecha")
ax.legend()
fig.autofmt_xdate()
print("Gráfica 2. Mediciones de Ozono del 13 al 15 de Marzo del 2019")
Gráfica 2. Mediciones de Ozono del 13 al 15 de Marzo del 2019

Podemos representar de otra forma los datos si cambiamos los intervalos y el tipo de código de las gráficas.

In [9]:
import pandas as pd
import matplotlib.pyplot as plt
data=pd.read_csv("archivo02.csv", sep=",", header=4, na_values=-99,index_col=0,parse_dates=True)
print(data)
                      AJU   MGH
FECHA                          
2019-01-01 01:00:00   NaN   NaN
2019-01-01 02:00:00   NaN   NaN
2019-01-01 03:00:00   NaN   NaN
2019-01-01 04:00:00  14.0   2.0
2019-01-01 05:00:00  16.0   2.0
...                   ...   ...
2019-12-31 20:00:00   NaN  18.0
2019-12-31 21:00:00   NaN  15.0
2019-12-31 22:00:00   NaN   9.0
2019-12-31 23:00:00   NaN   4.0
2019-12-31 00:00:00   NaN   2.0

[8760 rows x 2 columns]
In [10]:
data["Año"]=data.index.year
data["Mes"]=data.index.month
data["Dia"]=data.index.day

data.sample(5,random_state=0)
Out[10]:
AJU MGH Año Mes Dia
FECHA
2019-06-19 04:00:00 NaN 9.0 2019 6 19
2019-10-16 03:00:00 NaN NaN 2019 10 16
2019-01-10 18:00:00 NaN 56.0 2019 1 10
2019-02-10 23:00:00 18.0 13.0 2019 2 10
2019-09-06 16:00:00 108.0 86.0 2019 9 6
In [32]:
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(rc={"figure.figsize":(20,4)})
cols_plot = ['AJU', "MGH"]
axes = data[cols_plot].plot(marker='.', alpha=0.5, linestyle='None', figsize=(11, 9), subplots=True,label="Niveles de Ozono")
for ax in axes:
    ax.set_ylabel('Ozono(ppb)')
print("Gráfica 3. Registro de Ozono por separado de las estaciones MGH y AJU del año 2019")
Gráfica 3. Registro de Ozono por separado de las estaciones MGH y AJU del año 2019
In [14]:
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(rc={"figure.figsize":(20,4)})
ax=data.loc["2019-07","AJU"].plot(label="AJU")
ax=data.loc["2019-07","MGH"].plot(label="MGH")
ax.legend()

ax.set_ylabel("Niveles de ozono(ppb)")
print("Gráfica 4.Registros de Ozono del mes de Julio del 2019")
Gráfica 4.Registros de Ozono del mes de Julio del 2019
In [15]:
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(rc={"figure.figsize":(20,4)})
ax=data.loc["2019-01":"2019-07","AJU"].plot(label="AJU")
ax=data.loc["2019-01":"2019-07","MGH"].plot(label="MGH")
ax.legend()
ax.set_ylabel("Niveles de ozono(ppb)")
fig.autofmt_xdate()
print("Gráfica 5. Registro de Ozono en el primer semestre del año 2019")
Gráfica 5. Registro de Ozono en el primer semestre del año 2019

Para hacer este tipo de gráficas nos basamos en el trabajo de Walker, J. (2020, 27 octubre).

Análisis

Después de hacer diversas representaciones gráficas de los datos podemos observar un comportamiento variado, ya que las partículas de ozono no aumentan con respecto al tiempo, esto se debe a que a pesar de que la variable es dependiente no es proporcional al tiempo, sino más bien a otras variables, tales como patrones de viento y temperatura.

Los metadatos de nuestro archivo nos proporcionaron información suficiente para investigar acerca de las estaciones de monitoreo atmosférico donde fueron obtenidos. Al investigar sobre la Red automática de monitoreo atmosférico de la ciudad de México buscamos la ubicación de las estaciones con abreviatura AJU y MGH .Podemos ver que AJU es la abreviatura de la estación Ajusco ubicada en Tlalpan y MGH corresponde a la estación ubicada en la delegación Miguel Hidalgo.

Nuestra base de datos abarca el monitoreo del año 2019, presentando un formato de fecha (AAAA-MM-DD) y hora.

Para explicar un poco de qué puede generar los cambios en nuestros datos encontramos lo siguiente: La concentración troposférica del ozono, que no es emitida de forma directa a la atmósfera, más bien es el resultado de mecanismos fotoquímicos de una gran variedad de precursores naturales y antropogénicos, como los componentes orgánicos no volátiles (VOC) óxidos de carbono (CO_X) y oxidos de nitrogeno(No_x), que se generan por el escape de los choches y actividades industriales , las concentraciones en un lugar determinado dependen de la proximidad con grandes fuentes precursoras de ozono, las condiciones meteorologicas prevalentes, el intercambio estratosfera-troposfera y el transporte atmosférico de largo alcance(Silva-Quiroz, et.al,2019), de acuerdo con la Agencia de Protección Ambiental, exposiones a niveles de ozono mayores a 70 ppb por un periodo de 8 horas o más es malo para la salud, en México el límite es a partir de las 95 ppb , después de estos niveles se declara una contingencia ambiental(NASA,2018).

Los niveles de emisiones de ozono aumentan a cierta hora del día, por ejemplo el 03/07/19 los niveles son menores al inicio del día, es aproximadamente a partir de las 6:00 AM que aumentan los niveles de ozono, pues la temperatura va en aumento por la radiación del sol; también influye el tráfico que mientras va atardeciendo aumenta por las actividades de la gente, hasta un periodo entre las 18:00 y 20:00, que es cuando empiezan a decrecer los niveles de ozono. Los niveles llegan a un número muy cercano a 70. Por otro lado si analizamos la gráfica 03/01/19 las emisiones se mantienen bajas desde las 12:00 a las 9:00 AM, que es cuando van en aumento hasta aproximadamente las 18:00 PM, que es cuando empieza a decrecer el nivel. Esto se puede deber a las bajas temperaturas de Enero, aunque en el pico de emisiones se llega a un nivel muy cercano a 80 ppb.

In [27]:
import pandas as pd
import matplotlib.pyplot as plt
data=pd.read_csv("archivo02.csv", sep=",", header=4, na_values=-99,index_col=0,parse_dates=True)
print(data)
                      AJU   MGH
FECHA                          
2019-01-01 01:00:00   NaN   NaN
2019-01-01 02:00:00   NaN   NaN
2019-01-01 03:00:00   NaN   NaN
2019-01-01 04:00:00  14.0   2.0
2019-01-01 05:00:00  16.0   2.0
...                   ...   ...
2019-12-31 20:00:00   NaN  18.0
2019-12-31 21:00:00   NaN  15.0
2019-12-31 22:00:00   NaN   9.0
2019-12-31 23:00:00   NaN   4.0
2019-12-31 00:00:00   NaN   2.0

[8760 rows x 2 columns]
In [28]:
data["Año"]= data.index.year
data["Mes"]= data.index.month
data["Dia"]= data.index.day

data.sample(5,random_state=0)
Out[28]:
AJU MGH Año Mes Dia
FECHA
2019-06-19 04:00:00 NaN 9.0 2019 6 19
2019-10-16 03:00:00 NaN NaN 2019 10 16
2019-01-10 18:00:00 NaN 56.0 2019 1 10
2019-02-10 23:00:00 18.0 13.0 2019 2 10
2019-09-06 16:00:00 108.0 86.0 2019 9 6
In [31]:
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(rc={"figure.figsize":(6,4)})
ax=data.loc["2019-07-03","AJU"].plot(label="AJU")
ax=data.loc["2019-07-03","MGH"].plot(label="MGH")
ax.legend()
ax.set_ylabel("Niveles de ozono(ppb)")
print("Gráfica 6. Niveles de ozono del día 2 de Julio del 2019 ")
Gráfica 6. Niveles de ozono del día 2 de Julio del 2019 
In [34]:
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(rc={"figure.figsize":(6,4)})
ax=data.loc["2019-01-03","AJU"].plot(label="AJU")
ax=data.loc["2019-01-03","MGH"].plot(label="MGH")
ax.legend()
ax.set_ylabel("Niveles de ozono(ppb)")
print("Gráfica 7.Registro de ozono del tercer día de enero")
Gráfica 7.Registro de ozono del tercer día de enero

Nuestra base de datos no presenta una dependencia del tiempo.Ambas columnas indican los niveles de ozono en diferentes periodos de tiempo, además de que se ubican en la CDMX

Basandonos en los registros de Ozono de estas estaciones podemos ver que AJU no registra niveles en ciertos meses a ciertas horas, como en las fechas 19/06/19, 16/10/19 ó 10/01/19, ya que los registros son de -99 (Gráfica 3). También hay fechas en las que ni AJU ni MGH registran el ozono. Sin embargo, suelen coincidir en el nivel de ozono, con pequeñas diferencias en los registros debido a la zona en que se ubican en diferentes estaciones.

Si comparamos los datos entre diversos periodos resulta más notorio que la estación AJU no tiene registros en ciertas fechas (Gráfica 5). También podemos ver que los mayores niveles de ozono registrados se dan entre Mayo y Julio, un factor determinante es la alta temperatura en dichos meses, ya que actua como un catalizador para la formación de ozono y modifica la capa límite de la atmósfera y su interacción con la inversión térmica, ya que en los meses más cálidos es cuando la zona más baja de la troposfera se calienta y por lo tanto se hace más densa, lo que propicia la concentración de contaminantes en una menor área, y decrece en Diciembre y Enero, ya que al disminuir la temperatura el área que ocupa la capa límite de la atmósfera aumenta, ocasionando que los contaminantes se dispersen (Burgos,2019).

Para realizar mediciones de O3 existen diversos métodos. A continuación presentamos unos de los más comunes.

TÉCNICAS DE MEDICIÓN DE OZONO

FOTÓMETROS SOLARES.El principio de medición de estos instrumentos se basa en la ley de absorción de Beer-Lambert que consiste en relacionar la intensidad de luz entrante en un medio con la intensidad saliente después de que en dicho medio se produzca absorción.El ozono presenta una fuerte absorción entre los 300nm y los 350nm (bandas de Huggings); por lo tanto, el espectrofotómetro de Dobson utiliza pares de longitudes de onda en esta franja del espectro. Para realizar la medición, este instrumento descompone la luz solar en su espectro mediante prismas monocromáticos, y mediante fotodetectores mide la intensidad de luz entre cada par de longitudes de onda.

EL MÉTODO LIDAR (Light Detection And Ranging) Se puede determinar la densidad atmosférica a partir de la detección de luz dispersada de un haz de luz proyectado a la atmosfera.

MÉTODO DE QUIMIOLUMINISCENCIA La quimioluminiscencia es una de las técnicas utilizada para la medida en continuo de ozono en aire ambiente. y se basa en la detección de fotones producidos en la reacción exotérmica entre Etileno (C2H4 ) y Ozono (03 ).

MEDIDORES DE OZONO PASIVOS

Los captadores pasivos para la recepción de gases se rigen por la Ley de Fick, la cual relaciona el flujo de un gas que difunde desde una región de alta concentración (extremo abierto del tubo), con el tiempo de exposición y elárea del captador, que está expuesto al contaminante.

En 1991 desarrollan en la Universidad de Harvard, el captador pasivo para ozono "Ogawa", basado en la impregnación de los filtros captadores con una solución de iones Nitrito que al reaccionar con ozono se oxidan a ión Nitrato. La cantidad de ozono se obtiene al medir por cromatografía iónica el volumen de iones Nitrato. El captador pasivo Ogawa consta de un cuerpo polimérico cilíndrico (de 2 cm de diámetro x 3cm de longitud) y un broche dentado (4 x 3 cm). Tiene dos cavidades en los extremos del cilindro, cada una de las cuales custodia entre dos rejillas de acero inoxidable un filtro impregnado. Las cápsulas de difusi}ón cubren y fijan los filtros y las rejillas (Ospina,et. al,2013).

Conclusión

Si hay algo todavía más importante que los propios datos recabados en una investigación es el saber analizarlos, y para esto es fundamental saber buscar y preguntar las dudas de una manera acertada.La programación a diferencia de otras disciplinas no tiene una manera concreta o única de llegar a un camino, sino más bien con diferentes herramientas puedes construir lo que más se acomode tanto a tus necesidades de aprendizaje como de tu propio análisis de datos, porque basandonos en un archivo simple logramos obtener información que va más allá de solo números.

Bibliografía consultada

  • Gutiérrez-Avella, D. M., & Guardado-Pérez, J. A. (2010). Formas de expresar la composición química en el SI. Educación química, 21(1), 47-52.
  • Silva-Quiroz, R., Rivera, A. L., Ordoñez, P., Gay-Garcia, C., & Frank, A. (2019). Atmospheric blockages as trigger of environmental contingencies in Mexico City. Heliyon, 5(7), e02099. https://doi.org/10.1016/j.heliyon.2019.e02099