Codea Blog  

Blog Details

Análisis de series temporales geológicas utilizando Python

Introducción

Una serie de tiempo es una secuencia de datos u observaciones medidos en determinados momentos, en intervalos iguales o desiguales, y ordenados cronológicamente.

 

El análisis de series de tiempo se refiere al proceso de analizar los datos disponibles para descubrir el patrón o la tendencia en los datos. Permite extraer y modelar las relaciones entre datos a lo largo del tiempo, sea extrapolando (hacia futuro) o interpolando (hacia el pasado) el comportamiento de datos no observados.

 


 

Análisis Exploratorio

Dentro del análisis exploratorio de series de tiempo, se pueden llevar a cabo diferentes procedimientos para comprender y estudiar las características de los datos temporales. Algunos de estos procedimientos incluyen:

 

• Estimación de tendencias y descomposición: Este proceso se enfoca en ajustar los componentes estacionales de una serie temporal observada. Se busca descomponer la serie en sus subcomponentes, como tendencia, estacionalidad y residuos, para entender mejor los patrones a lo largo del tiempo.

• Análisis de autocorrelación: El análisis de autocorrelación es útil para entender la relación entre los valores pasados y el valor actual de una serie temporal. Se utilizan funciones de autocorrelación para estimar los órdenes de los términos autorregresivos (AR), integrados (I) y de promedio móvil (MA) en modelos ARIMA.

• Análisis espectral: El análisis espectral se centra en describir cómo la variación en una serie de tiempo puede explicarse por componentes cíclicos o frecuencias específicas. Permite identificar patrones periódicos en medio del ruido y entender mejor la influencia de ciclos en los datos temporales.

 

El primer paso del análisis exploratorio implica leer y transformar los datos en formato de series de tiempo. La función "ts()" se utiliza para convertir los datos en una serie de tiempo, lo que facilita la representación gráfica de los datos. Además, la función "window()" se emplea para extraer información de una ventana de tiempo específica dentro de la serie, lo que puede ser útil para un análisis detallado en intervalos particulares.

 

En resumen, el análisis exploratorio de series de tiempo es un proceso crucial para comprender los patrones, tendencias y características cíclicas en los datos temporales, y Python ofrece diversas herramientas y funciones, como las mencionadas anteriormente, para facilitar este análisis y visualización.

 

COMPONENTES DE LA SERIE

La serie de tiempo es una secuencia de datos que se registran a lo largo del tiempo. En el análisis de series temporales, podemos identificar diferentes patrones y características en los datos:

 

• Tendencia: Es el patrón subyacente en los datos que muestra una dirección general en el tiempo. La tendencia puede ser ascendente, descendente o plana, y no siempre sigue una forma lineal.

• Estacionalidad: Cuando una serie muestra patrones recurrentes o cíclicos que se repiten en períodos fijos, como días, meses o trimestres. Estos patrones estacionales pueden estar influenciados por factores como la temporada del año o eventos regulares.

• Cíclicidad: Se refiere a las fluctuaciones que ocurren en la serie de tiempo con una duración más larga que la estacionalidad. Estas subidas y caídas pueden no tener un período fijo y suelen extenderse al menos durante varios años.

• Aleatoriedad: Es la parte de los datos que no sigue ningún patrón discernible y no puede explicarse por la tendencia, la estacionalidad o la cíclicidad. Se considera como el componente inexplicable de la serie de tiempo.

 


Aplicaciones en Geología

Las áreas más usuales donde se aplica Python, son:

 

Geoestadística: En esta área se utiliza para variogramas,en el análisis y modelado de datos geoespaciales. Esta disciplina es útil para comprender y modelar fenómenos naturales que presentan una estructura espacial. En Python, puedes utilizar diversas bibliotecas para trabajar con datos geoespaciales y aplicar técnicas de geoestadística. Algunas bibliotecas populares para la manipulación y análisis de datos geoespaciales son:

 

• GeoPandas: Proporciona herramientas para trabajar con datos geoespaciales en formato de DataFrames, permitiendo realizar operaciones de manera similar a la biblioteca pandas.

• Shapely: Ofrece funciones para manipular y analizar geometrías geoespaciales.

• Fiona: Permite leer y escribir datos geoespaciales en diferentes formatos, como shapefile y GeoJSON.

 

Geoquímica: Destacan pyrolite y diagrama de clasificación QAP, donde la primera es una biblioteca de Python diseñada para el análisis geoquímico y petrogenético de rocas ígneas y metamórficas. Proporciona herramientas para manejar datos geoquímicos, realizar cálculos geoquímicos y visualizar resultados de forma eficiente. La biblioteca "pyrolite" es una extensión del paquete "pandas" y está especialmente orientada a trabajar con datos de geoquímica y petrología. Algunas de las funcionalidades que ofrece son:

 

• Lectura y escritura de datos geoquímicos: Pyrolite permite leer y escribir archivos de datos geoquímicos en diferentes formatos, como archivos CSV o Excel.

• Cálculos geoquímicos: La biblioteca proporciona una amplia gama de métodos para realizar cálculos geoquímicos comunes, como la normalización de elementos, la clasificación de rocas, cálculos de variables geoquímicas y otros análisis petrogenéticos.

• Visualización de datos geoquímicos: Pyrolite integra herramientas de visualización con bibliotecas populares como Matplotlib y Plotly para crear gráficos interactivos y de alta calidad que permiten explorar y presentar datos geoquímicos.

 

El diagrama QAPF es actualmente el diagrama más "oficial" en la denominación de las rocas ígneas. El diagrama permite en una manera bastante fácil la denominación de rocas plutónicas y volcánicas. Solamente el contenido modal de 4 minerales en una muestra (y la textura) definen al final el nombre de la roca. Existen solamente pocas excepciones: Nombres como "ignimbrita" o piedra pómez no tienen su origen en este diagrama. Además todas las rocas con un contenido menor de 10 % en Q-A-P-F, significa sí la suma del contenido modal en cuarzo + feldespato alcalino + plagioclasa + feldespatoides no alcanza 10 %) se tratan en un otro diagrama, el diagrama de los ultrabásicos.

 

Análisis geoespacial: Se emplea Shapely, una biblioteca de Python que proporciona herramientas para el análisis geométrico y el procesamiento de datos geoespaciales. Con Shapely, puedes realizar operaciones con geometrías como puntos, líneas, polígonos, círculos y otros objetos geométricos. Esta biblioteca es muy útil para trabajar con geometrías geoespaciales, calcular áreas, longitudes, distancias, intersecciones, uniones y otras operaciones espaciales. Otra es geopandas, una extensión de la biblioteca Pandas de Python que agrega soporte para datos geoespaciales.

 

Geopandas combina la capacidad de manipulación de datos tabulares de Pandas con las funcionalidades de Shapely para trabajar con datos geoespaciales de una manera eficiente. Permite leer, escribir, manipular y analizar datos geoespaciales en formatos como shapefile, GeoJSON y otros. Rioxarray es una biblioteca que extiende xarray, una biblioteca de análisis de datos etiquetados de Python, para trabajar con datos raster geoespaciales. Permite leer y escribir datos raster en diversos formatos, así como realizar operaciones y análisis espaciales en datos raster.

 

Leafmap es una biblioteca de Python que proporciona herramientas para crear visualizaciones interactivas de datos geoespaciales directamente desde Jupyter Notebooks. Utiliza bibliotecas como folium, ipyleaflet y ipywidgets para generar mapas interactivos con facilidad. Leafmap es especialmente útil para visualizar datos geoespaciales de manera rápida y sencilla.

 

Geofísica: Se utiliza para la visualización de registro de pozos en la industria del petróleo y el gas para analizar y comprender las características geológicas y petrofísicas de un pozo. Python ofrece varias bibliotecas que facilitan la visualización de registros de pozo. Algunas de las bibliotecas más utilizadas son Matplotlib, pandas y las bibliotecas específicas para la visualización de registros de pozo como las de las suitesde software "Welly" y "Lasio".

 

Estratigrafía y Sedimentología: Se utiliza Stratilib para las columnas estratigráficas.

 

Geología Estructural: En geología estructural y tectónica, un estereoneta es un tipo de proyección utilizada para representar la orientación de planos geológicos y líneas de estrías en el espacio tridimensional. Para visualizar y analizar datos de estereonetas en Python, una de las bibliotecas más conocidas y utilizadas en "mplstereonet", que proporciona herramientas para crear gráficos de estereonetas de manera interactiva y eficiente utlizando Matplotlib.

 

Geotecnia: Se utiliza para la estimación de la probabilidad de fallo en un talud, geotécnica y geomecánica que involucra el análisis de la estabilidad del talud y la evaluación de los factores que pueden llevar el deslizamiento o colapso del terreno. Hay varios métodos y enfoques para realizar esta estimación, dependiendo de la complejidad del talud y la disponibilidad de datos. Una forma común de estimar la probabilidad de fallo en un talud es mediante el análisis probabilístico de la estabilidad. En este enfoque, se consideran incertidumbres en los párametros geotécnicos y las cargas aplicadas, y se utilizan técnicas como el método de Monte Carlo para simular diferentes escenarios y calcular la probabilidad de que el talud falle.

 

En Python, puedes utilizar bibliotecas como NumPy para el cálculo numérico, y Scipy para realizar simulaciones y análisis probabilísticos. Además, es posible que necesites herramientas específicas para el análisis geotécnico y de estabilidad de taludes, como el software GeoStudio, que tiene una interfaz de Python para realizar análisis geotécnicos avanzados.Es importante tener en cuenta que el análisis de la estabilidad de taludes es una tarea compleja y crítica para la seguridad de las infraestructuras y las personas. Se recomienda que este tipo de análisis sea realizado por ingenieros geotécnicos y especialistas capacitados en el campo.

 

DEMOSTRACIÓN

A continuación se muestra un ejemplo Pastas es un framework de Python diseñado para el análisis de series temporales hidrogeológicas. Es un código abierto que facilita el procesamiento, simulación y análisis de modelos hidrogeológicos. Ofrece herramientas para el análisis estadístico y la visualización de estos modelos. Para instalar Pastas, simplemente ejecuta el siguiente comando.

 

 pip install pastas

 

 

Una vez instalado se procede a importar las librerías que permitirán visualizar los datos importados.

 

 import pandas as pd

 #for data manipulation

 import pastas as ps

 #for visualization

 import matplotlib.pyplot as plt

 

Se procede a cargar la información, para este caso, se ejemplifica con una archivo head_nb1.csv, que contiene la información necesaria.

 

 head_data = pd.read_csv ( 'head_nb1.csv', parse_dates = ['date'], index_col = 'date', squeeze = True )

 

Se verifican el tipo de dato y si estos fueron cargados correctamente a través de este código:

 

 print 'Data type of head_data :', type (head_data) )

 

Output : 

 

 Data type of head_data: <class 'pandas.core.series.Series'>

 

 head(head_data)

 

Output:

 

  date:

  1985-11-14    27.61

  1985-11-28    27.73

  1985-12-14    27.91

  1985-12-28    28.13

  1986-01-13    28.32

  Name: head, dtype: float64

 

Si se requiere plotear las observaciones head :

 

  #Size of plot

  head_data.plot ( style'.', figsize = (12, 4) ) 

  #Y-axis label

  plt.ylabel 'Head (metres)' );

  #X-axis label

  plt.xlabel 'Year' )

 

Se cargan las tensiones, dado que se percibe que las variaciones de altura son la lluvia y evaporación del agua. 

 

  # Load rain

  data rain = pd.read_csv ('rain_nb1.csv', parse_dates = ['date'], index_col='date', squeeze=True)

   # Initial records  

  rain.head( )

 

Output :

 

  date

  1980-01-01    0.0033

  1980-01-02    0.0025

  1980-01-03    0.0003

  1980-01-04    0.0075

  1980-01-05    0.0080

  Name: rain, dtype: float64

 

  # Load evaporation data

  evap = pd.read_csv ( 'evap_nb1.csv', parse_dates = ['date'], index_col='date', squeeze=True)

  # Initial records

  evap.head ( )

 

Output:

 

  date

  1980-01-01    0.0002

  1980-01-02    0.0003

  1980-01-03    0.0002

  1980-01-04.   0.0001

  1980-01-05.   0.0001

  Name: evap, dtype: float64


Para plotear la lluvia y evaporación de las series temporal.

 

  #Title for rain plot

  rain.plot ( label = 'rain' )

  #Title for evaporation plot

  evap.plot ( label = 'evap' )

  #X-axis label

  plt.xlabel (‘Year')

  #Y-axis label

  plt.ylabel ( 'Rainfall/Evaporation (m/d)' )

  # Location of legend

  plt.legend ( loc = 'best' );

 

Calcular y plotear la recarga de agua subterránea, con lo cual se aproxima con la diferencia entre la lluvia y nivel de evaporación.

 

  # Plot the recharge time series

  recharge = rain - evap

  #Size of plot

  plt.figure ( figsize = (12, 4) ) recharge.plot ( )

  #X-axis label

  plt.xlabel ( 'Year' )

  #Y-axis label

  plt.ylabel ( 'Recharge (m/d)' )

 

Para la creación de modelos de series temporales, se inicia el modelo de la serie temporal usando class Model.

 

  model = ps.Model(head_data)

  stressModel = ps.StressModel recharge, ps.Gamma, name'groundwater recharge', settings = 'prec' )

 

Para cada estrés, se crea un objeto StressModel. El primer parámetro es el nombre de la serie temporal de la tensión. El segundo argumento es la función de respuesta utilizada, 'nombre' especifica solo un nombre dado a la serie y 'prec' (significa 'precipitación') es el tipo de serie.

 

  model.add_stressmodel(stressModel)

 

Para resolver el modelo para un período de tiempo específico (tmin a tmax). Aquí se puede encontrar diferentes soluciones.

 

  model.solve ( tmin='1990', tmax='2015' )

 

Otro ejemplo, consta de analizar diferentes datos de pozos de la plataforma continental noruega y extracción de la composición litológica del grupo Zechstein.

Con lo cual se procede a importar las bibliotecas y cargar los datos.

 

  import pandas as pd

 

Una vez importado, se lee el archivo CSV, donde dicho archivo contiene datos separados por punto y coma.

 

  df = pd.read_csv ( 'data/train.csv', sep = ';' )

 

Al ejecutar dicho código, este procede a mostrar los datos en la siguiente imagen.

 

 

Dentro de este conjunto de datos, los datos de litología se almacenan en la columna FORCE_2020_LITHOFACIES_LITHOLOGY. Sin embargo, cuando miramos de cerca nuestros datos, veremos que los valores de litología están codificados numéricamente. A menos que conozca la clave, será difícil descifrar qué número representa qué litología.

 

Afortunadamente para este conjunto de datos, tenemos la clave y podemos crear un diccionario con los pares de clave y litología.

Tal como se muestra a continuación.

 

  lithology_numbers = 30000: 'Sandstone',

                                       65030: 'Sandstone/Shale',

                                       65000: 'Shale',

                                       80000: 'Marl',

                                       74000: 'Dolomite',

                                       70000: 'Limestone',

                                       70032: 'Chalk',

                                       88000: 'Halite',

                                       86000: 'Anhydrite',

                                       99000: 'Tuff',

                                       90000: 'Coal',

                                       93000: 'Basement' }

 

Para aplicar esto a nuestro conjunto de datos, podemos usar la función pandas map(), que realizará una búsqueda usando nuestro diccionario y luego asignará la etiqueta de litología correcta al valor numérico.

 

  df ['LITH'] = df [ 'FORCE_2020_LITHOFACIES_LITHOLOGY' ]..map(lithology_numbers)

 

Se procede a comprobar la información, con lo que muestra.

 

 

En resumen, para simplificar el análisis de composición de litología en un conjunto de datos grande con 11,705,511 filas, se ha decidido enfocarse en un grupo geológico específico, en este caso, el Grupo Zechstein. Esto se logrará utilizando el método query() y filtrando las filas en las que el valor de la columna "GRUPO" sea igual a "ZECHSTEIN GP". De esta manera, se limitará el análisis a los datos relevantes para ese grupo geológico en particular.

 

  df_zechstein = df.query ( 'GROUP == "ZECHSTEIN GP."' )

  df_zechstein.WELL.unique ( )

 

Al usar "df_zechstein.WELL.unique()", podemos determinar la cantidad de pozos en el subconjunto. En este caso, la matriz resultante contiene 8 pozos diferentes.

 

  array ( [ '15/9-13', '16/1-2', '16/10-1', '16/11-1 ST3', '16/2-16', '16/2-6','16/4-1', '17/11-1' , dtype = object )

 

Dado que nuestro enfoque se centra en las litologías, podemos simplificar extrayendo únicamente el nombre del pozo y las columnas relacionadas con la litología. Esta estrategia también simplificará el proceso de agregación.

 

  df_zechstein_liths = df_zechstein [ [ 'WELL', 'LITH' ] ]

 

 

Vamos a simplificar y optimizar el proceso de agregación de datos utilizando una cadena de funciones de pandas. Primero, agruparemos los datos por el nombre del pozo utilizando "groupby". Esto crea subconjuntos para cada pozo único. Luego, contaremos las proporciones de cada tipo de litología en cada grupo utilizando "normalize=True" para obtener valores entre 0 y 1. Finalmente, reorganizaremos el resultado para tener nombres de pozos como índices de fila y nombres de litologías como columnas. En caso de que falte una litología en un pozo, se completará con ceros usando "fill_value=0".

 

  summary_df = df_zechstein_liths.groupby ( 'WELL' ).value_counts (normalize True).unstack ( fill_value 0)

  summary_df                                         

 

 

 

Si preferimos visualizarlos en forma de porcentajes, podemos ajustar su presentación mediante el siguiente código:

 

  summary_df.style.format ( ' { :.2% } ' )

 

 

 

Si deseamos convertir los valores de manera duradera a porcentajes, podemos lograrlo al multiplicar todo el marco de datos por 100.

 

  summary_df = summary_df * 100

  summary_df

 

 

 

En este breve artículo, hemos explorado cómo manejar una extensa recopilación de registros de pozos, abarcando más de 90 pozos. Aprendimos a extraer y sintetizar datos específicos de un grupo geológico en particular. Este enfoque nos brinda la capacidad de comprender la composición de litologías dentro del grupo geológico, presentándola de manera legible y comprensible, lo que resulta idóneo para su inclusión en informes o presentaciones.

 


 

Bibliografía

1. (S/f). Bookdown.org. Capítulo 8 Análisis de Series de Tiempo. https://bookdown.org/keilor_rojas/CienciaDatos/análisis-de-series-de-tiempo.html

2. Shiledarbaxi, N. (2021). Guide To Pastas: A Python Framework For Hydrogeological Time Series Analysis. Analytics India Magazinehttps://analyticsindiamag.com/guide-to-pastas-a-python-framework-for-hydrogeological-time-series-analysis/

3. McDonald, A. (2023, June 30). Data Aggregation in Python with Pandas: Analysing Geological Lithology Data.Mediumhttps://towardsdatascience.com/data-aggregation-in-python-with-pandas-analysing-geological-lithology-data-94192f5631c0

Comentarios

Registrate o Inicia Sesión para comentar y obtener Cursos de pago gratis

function loadurl(){ var val1 = document.getElementById("valor3").value; console.log(val1); if(val1){ window.location = "/comunidad/blog/filtrar/"+val1+"/"} }