Skip to article frontmatterSkip to article content

Formato Zarr para Datos Científicos

Formato Zarr para Datos Científicos


📚 Descripción general

En este cuadernillo aprenderás todo sobre Zarr, el formato ARCO más usado para datos científicos multidimensionales:

  1. ¿Qué es Zarr? - Conceptos fundamentales (Store, Group, Array)

  2. Exportar a Zarr - Convertir datos radar a formato Zarr

  3. Carga perezosa - Trabajar con archivos sin cargarlos en memoria

  4. Fragmentación - Optimizar rendimiento según tu caso de uso

  5. Metadatos - Inspeccionar estructura interna de archivos Zarr

Trabajarás con datos reales de radar meteorológico colombiano.

✅ Requisitos previos

ConceptoImportanciaNotas
Introducción a ARCONecesarioConceptos ARCO y FAIR
Introducción a RadarNecesarioDatos radar meteorológico
XarrayNecesarioManipulación de datos multidimensionales

⏱️ Tiempo estimado de aprendizaje:

  • 📖 Solo lectura: 15–20 minutos

  • 🏋️ Con actividades prácticas: 25–30 minutos

✍️ Formato: práctico, ejecuta y modifica el código

Librerías

Importamos las librerías necesarias para este cuaderno.

import xarray as xr  # Estructuras de datos multidimensionales
import xradar as xd  # Lectura y manipulación de datos radar
import zarr  # Formato de almacenamiento optimizado
import numpy as np  # Operaciones numéricas
import matplotlib.pyplot as plt  # Visualización
import cmweather  # Colormaps meteorológicos
import os  # Operaciones del sistema de archivos
from pathlib import Path  # Manejo de rutas

1. ¿Qué es Zarr?


Zarr es un formato para almacenar grandes arrays N-dimensionales — en fragmentos (chunks) — con metadatos, diseñado para acceso rápido y paralelo desde almacenamiento local o en la nube.

Conceptos clave de Zarr: Store y Group. Imagen cortesía: Earthmover

Figure 1:Conceptos clave de Zarr: Store y Group. Imagen cortesía: Earthmover

Conceptos clave de Zarr:

Store (Almacén):

  • Un directorio en disco (e.g., LocalStore)

  • Un bucket en la nube (e.g., FsspecStore para s3://…)

  • En memoria (e.g., MemoryStore)

Group (Grupo):

  • Un grupo puede contener múltiples arrays Zarr relacionados

  • Puede contener otros grupos (jerarquía anidada)

  • Cada grupo tiene sus propios metadatos (en zarr.json)

Ventajas de Zarr:

📦 Compresión - Para ahorrar espacio de almacenamiento
🔀 Acceso paralelo - Por múltiples usuarios simultáneamente
📡 Transmisión eficiente - Desde almacenamiento en nube
Procesamiento bajo demanda - Sin necesidad de descargar todo

Piensa en ello como tener una biblioteca donde puedes tomar solo los libros que necesitas, ¡en lugar de tener que llevarte toda la biblioteca!

Características clave de Zarr

  1. Formato abierto y libre - No propietario, código abierto

  2. Compatible con NumPy - Se integra perfectamente con el ecosistema científico de Python

  3. Compresión flexible - Múltiples algoritmos de compresión disponibles

  4. Metadatos integrados - Autodescriptivo, similar a NetCDF

  5. Almacenamiento jerárquico - Soporta estructuras de grupos anidados

  6. Optimizado para nube - Diseñado desde el inicio para object storage (S3, GCS, Azure)

Zarr vs NetCDF: Comparación

CaracterísticaNetCDFZarr
FragmentaciónLimitadaFlexible y optimizada
Acceso paraleloDifícilNativo
Almacenamiento nubeIneficienteOptimizado
CompresiónLimitadaMúltiples opciones
Escritura concurrenteNo
Tamaño máximoLimitado por formatoSin límite práctico
MadurezMuy maduroEn crecimiento rápido

2. Exportar Datos a Zarr

Ahora que entiendes qué es Zarr, ¡veámoslo en acción! Vamos a:

  1. Cargar datos radar del cuadernillo anterior (1.5)

  2. Exportarlos al formato Zarr

  3. Examinar la estructura del archivo Zarr resultante

# Cargar datos radar usando xradar (del cuadernillo 1.5)
archivo_radar = "../data/CAR220809191504.RAWDSX2"
%%time
radar_dt = xd.io.open_iris_datatree(archivo_radar)
CPU times: user 1.53 s, sys: 45 ms, total: 1.58 s
Wall time: 5.52 s
print("Datos radar cargados:")
radar_dt
Loading...
# Exportar a Zarr
# Especificamos zarr_version=2 para compatibilidad amplia
zarr_path = "../data/radar_carimagua.zarr"

# Eliminar si existe para evitar errores
import shutil
if os.path.exists(zarr_path):
    shutil.rmtree(zarr_path)

# Exportar el DataTree completo
radar_dt.to_zarr(zarr_path, mode="w", zarr_version=2, consolidated=True)

print(f"✅ Datos exportados a: {zarr_path}")
/tmp/ipykernel_4306/551436027.py:11: FutureWarning: zarr_version is deprecated, use zarr_format
  radar_dt.to_zarr(zarr_path, mode="w", zarr_version=2, consolidated=True)
/home/runner/micromamba/envs/cdh-python/lib/python3.13/site-packages/xradar/io/backends/iris.py:249: RuntimeWarning: invalid value encountered in sqrt
  return np.sqrt(decode_array(data, **kwargs))
✅ Datos exportados a: ../data/radar_carimagua.zarr
# Examinar estructura del archivo Zarr
# Zarr almacena datos en una estructura de directorio
print("Estructura del archivo Zarr:")
print("\nPrimeros 20 archivos/directorios:")
for i, (root, dirs, files) in enumerate(os.walk(zarr_path)):
    if i > 5:  # Limitar salida
        break
    level = root.replace(zarr_path, '').count(os.sep)
    indent = ' ' * 2 * level
    print(f"{indent}{os.path.basename(root)}/")
    subindent = ' ' * 2 * (level + 1)
    for file in files[:5]:  # Mostrar solo primeros 5 archivos por directorio
        print(f"{subindent}{file}")
Estructura del archivo Zarr:

Primeros 20 archivos/directorios:
radar_carimagua.zarr/
  .zattrs
  .zmetadata
  .zgroup
  sweep_0/
    .zattrs
    .zgroup
    sweep_fixed_angle/
      .zattrs
      .zarray
      0
    elevation/
      .zattrs
      .zarray
      0
    prt_mode/
      .zattrs
      .zarray
      0
    WRADH/
      1.0
      1.1
      .zattrs
      3.1
      0.1

3. Carga Perezosa (Lazy Loading)

Una de las ventajas más poderosas de Zarr es la carga perezosa (lazy loading). Esto significa que podemos abrir un archivo Zarr gigante sin cargar todos los datos en memoria. Solo se cargan los datos cuando realmente los necesitamos.

%%time
radar_zarr = xr.open_datatree( # Abrir archivo Zarr
    zarr_path, 
    engine="zarr",
    chunks={},
    consolidated=True
)
CPU times: user 59.5 ms, sys: 6.06 ms, total: 65.5 ms
Wall time: 134 ms
# Esto NO carga los datos en memoria, solo los metadatos
print("Archivo Zarr abierto:")
radar_zarr
Loading...
# Cargar solo un subconjunto de datos
subset = radar_zarr["sweep_0"]
subset 
Loading...
# Acceder a una variable específica
# Los datos aún no se cargan en memoria - están "lazy"
dbzh = radar_zarr["sweep_0"]["DBZH"]

print("Variable DBZH (lazy):")
dbzh
Loading...
# Visualizar el subconjunto
dbzh.plot(cmap="ChaseSpectral", vmin=-10, vmax=60)
plt.title("Reflectividad - Primeros 100 km, 0-180° azimuth")
plt.show()
<Figure size 640x480 with 2 Axes>

4. Actividades Prácticas

Ahora es tu turno de experimentar con Zarr. Estas actividades te ayudarán a dominar fragmentación, rendimiento y metadatos.


🏋️ Práctica 1: Exportar con fragmentación personalizada

Zarr permite especificar cómo se fragmentan (chunk) los datos. Una fragmentación óptima puede mejorar significativamente el rendimiento.

Contexto sobre fragmentación:

La fragmentación determina qué tamaño tienen los “bloques” de datos. Opciones comunes:

📏 Estrategias de fragmentación:

  • {azimuth: 180, range: 250} → Fragmentos de tamaño específico (bueno para acceso parcial)

  • {azimuth: -1, range: -1} → Un solo fragmento por dimensión (bueno para cargar dimensiones completas)

    • ¿Qué significa -1? → Toda la dimensión en un solo chunk (sin fragmentación adicional)

  • {azimuth: 360, range: 497} → Fragmentos medianos (balance entre los dos anteriores)

Tareas:

  1. Carga el dataset de radar nuevamente

  2. Accede al sweep_0 como Dataset

  3. Aplica fragmentación personalizada usando .chunk() con {azimuth: 180, range: 250}

  4. Exporta a Zarr con el nombre radar_chunked.zarr

  5. Compara el tamaño con la versión anterior

  6. Reflexión: ¿En qué caso de uso sería mejor cada estrategia de fragmentación?

# Tu código aquí

🏋️ Práctica 2: Comparar velocidad de acceso

Compara la velocidad de lectura entre el formato original y Zarr.

Tareas:

  1. Usa %%time para medir el tiempo de carga del archivo original

  2. Usa %%time para medir el tiempo de apertura del archivo Zarr (lazy)

  3. Mide el tiempo de cargar un subconjunto desde Zarr

  4. Explica las diferencias de rendimiento

# Tu código aquí

🏋️ Práctica 3: Inspeccionar metadatos Zarr

Contexto:

Zarr almacena metadatos en archivos JSON legibles por humanos. Esto te permite:

  • ✅ Verificar la compresión aplicada sin cargar datos

  • ✅ Confirmar el tamaño de fragmentos (chunks)

  • ✅ Entender el esquema de datos antes de procesarlos

  • ✅ Diagnosticar problemas de rendimiento

Los archivos clave son:

  • .zattrs: Atributos del grupo (metadatos personalizados)

  • .zarray: Metadata del array (forma, tipo, compresión, chunks)

  • .zgroup: Indica que es un grupo Zarr

Exploraremos estos archivos para entender cómo Zarr organiza la información.

Tareas:

  1. Lee el archivo .zattrs del grupo raíz de tu archivo Zarr

  2. Lee el archivo .zarray de la variable DBZH

  3. Identifica en el .zarray: tipo de compresión, forma del array, fragmentación, tipo de datos

  4. Explica qué significa cada campo y cómo afecta el rendimiento

# Tu código aquí

Resumen

En este cuadernillo dominaste el formato Zarr:

Conceptos fundamentales: Store, Group, Array, fragmentación

Exportación: Convertiste datos radar a formato Zarr cloud-optimized

Carga perezosa: Abriste archivos grandes sin cargar todo en memoria

Fragmentación: Optimizaste estrategias de chunking

Metadatos: Inspeccionaste estructura interna JSON

Rendimiento: Comparaste velocidad con formatos tradicionales

Ahora puedes trabajar eficientemente con grandes volúmenes de datos científicos usando formatos ARCO.

💡 ¿Cuándo usar Zarr vs NetCDF?

Usa Zarr cuando:

  • 📈 Datasets muy grandes (> 1 GB)

  • ☁️ Almacenamiento en nube (S3, GCS, Azure)

  • 🔀 Acceso paralelo por múltiples usuarios

  • ⚡ Acceso rápido a subconjuntos

  • 📊 Pipelines de análisis escalables

Usa NetCDF cuando:

  • 💾 Sistemas de archivos locales

  • 📁 Datasets pequeños (< 1 GB)

  • 🔒 Compatibilidad con software legacy

  • 📜 Estándares CF requeridos

¿Qué sigue?

Ahora que dominas los formatos de datos científicos (NetCDF, GRIB, Zarr), estás listo para aplicar estos conocimientos en el acceso y análisis de datos hidrometeorológicos reales.

Temas avanzados para explorar:

  • Kerchunk: Virtualización de NetCDF como Zarr sin conversión

  • Dask: Procesamiento paralelo y distribuido

  • Intake: Catálogos de datos ARCO

  • Pangeo: Ecosistema de análisis científico en la nube

Recursos recomendados:

👉 Continúa con: Sección 2 - Acceso a datos hidrometeorológicos


📚 Referencias

  • Miles, A. et al. (2022). Zarr: A format for the storage of chunked, compressed, N-dimensional arrays. https://zarr.dev

  • Abernathey, R. et al. (2021). Cloud-Native Repositories for Big Scientific Data. Computing in Science & Engineering, 23(2), 26-35.

  • WMO (2021). Manual on the WMO Integrated Global Observing System (WIGOS). WMO-No. 1160.

  • Helmus, J. J., & Collis, S. M. (2016). The Python ARM Radar Toolkit (Py-ART). Journal of Open Research Software, 4(1).