Zarr: Arrays Fragmentados Nativos de la Nube para Computación Científica
¿Qué es Zarr?
Zarr es un formato de almacenamiento de código abierto y biblioteca Python para arrays N-dimensionales fragmentados y comprimidos. Diseñado desde cero para la computación en la nube y distribuida, Zarr almacena cada trozo de un array como un objeto separado — en un directorio local, un bucket de S3, Google Cloud Storage, Azure Blob Storage o cualquier otro almacenamiento clave-valor — lo que permite lecturas y escrituras paralelas eficientes sin los cuellos de botella de bloqueo de archivos de formatos monolíticos como HDF5.
Zarr es ahora el formato estándar para datos climáticos a gran escala (el ecosistema Pangeo), genómica (AnnData .zarr), observación de la Tierra y conjuntos de datos de entrenamiento de aprendizaje automático donde arrays de escala terabyte deben leerse eficientemente desde almacenamiento de objetos.
Conceptos Fundamentales
Arrays y Trozos (Chunks)
Un array Zarr es conceptualmente idéntico a un array NumPy — una cuadrícula N-dimensional de datos tipados — pero su almacenamiento está fragmentado:
mi_array/ ← directorio del array Zarr
.zarray ← metadatos JSON (forma, dtype, forma de trozo, compresor)
.zattrs ← atributos JSON (unidades, coordenadas, etc.)
0.0.0 ← Trozo [0,0,0]
0.0.1 ← Trozo [0,0,1]
...
Cada archivo de trozo es un blob binario comprimido independiente. Leer un subconjunto del array solo lee los archivos de trozo relevantes.
Grupos
Los grupos Zarr son contenedores (directorios o espacios de nombres de prefijo en almacenamiento de objetos) que contienen arrays y otros grupos.
Almacenes (Stores)
La característica de diseño clave de Zarr es la abstracción de almacén — cualquier backend de almacenamiento clave-valor:
zarr.DirectoryStore('ruta/')— sistema de archivos localzarr.ZipStore('archivo.zarr.zip')— archivo ZIP únicos3fs.S3FileSystem() + zarr.storage.FSStore— AWS S3gcsfs.GCSFileSystem() + zarr.storage.FSStore— Google Cloud Storage
Trabajar con Zarr en Python
Crear Arrays
import zarr
import numpy as np
# Abrir/crear un almacén de directorio local
almacen = zarr.DirectoryStore('datos_clima.zarr')
raiz = zarr.group(store=almacen)
# Crear un array fragmentado y comprimido
temp = raiz.create_dataset(
'temperatura',
shape=(8760, 721, 1440), # horas × lat × lon (un año, 0,25° global)
chunks=(24, 90, 180), # un día × 10° lat × 20° lon
dtype=np.float32,
compressor=zarr.Blosc(cname='lz4', clevel=5, shuffle=zarr.Blosc.SHUFFLE),
fill_value=np.nan
)
# Adjuntar atributos de metadatos
temp.attrs['unidades'] = 'K'
temp.attrs['nombre_largo'] = 'Temperatura del aire a 2m'
Leer Datos — Rebanado Lazy
# Abrir almacén existente
raiz = zarr.open('datos_clima.zarr', mode='r')
temp = raiz['temperatura']
# Rebanado lazy — solo lee los trozos que se superponen con esta región
europa = temp[:, 400:560, 720:900] # forma (8760, 160, 180)
# Estadísticas sobre un subconjunto
enero = temp[0:744, :, :] # Enero (744 horas)
print(f"Media global enero: {enero[:].mean():.2f} K")
Acceso a la Nube — S3 Sin Descarga
import s3fs
import zarr
# Acceder a un conjunto de datos Zarr público en S3
s3 = s3fs.S3FileSystem(anon=True)
almacen = zarr.storage.FSStore('s3://era5-pds/zarr/2023/', fs=s3)
raiz = zarr.open(almacen, mode='r')
temp = raiz['air_temperature_at_2_metres']
# Leer solo Europa occidental, 1 de enero de 2023
ene1_europa = temp[0:24, 520:580, 720:780]
Zarr con Dask: Computación Paralela
import xarray as xr
# Abrir Zarr como Dataset xarray (añade etiquetas de coordenadas, convenciones CF)
ds = xr.open_zarr('s3://era5-pds/zarr/2023/', storage_options={'anon': True})
# Cálculo lazy — construye un grafo de tareas, no lee datos aún
media_anual = ds['air_temperature_at_2_metres'].mean(dim='time')
# Ejecutar en paralelo (lee trozos concurrentemente)
resultado = media_anual.compute()
resultado.to_netcdf('media_anual_2023.nc')
Zarr en los Principales Ecosistemas
- Pangeo — geociencia nativa en la nube: ERA5, proyecciones climáticas CMIP6, datos de satélite GOES-16 — todo en Zarr en S3
- OME-Zarr (NGFF) — estándar de microscopía biológica; imágenes de portaobjetos completos, pilas Z de hoja de luz almacenadas como pirámides Zarr multiescala
- AnnData — genómica de célula única: backends
.h5ad(HDF5) y.zarrpara flujos de trabajoscanpy - Kerchunk / VirtualiZarr — técnica de sistema de archivos de referencia para exponer archivos NetCDF/HDF5/GRIB2 como Zarr sin copiar datos
Comparación: Zarr vs. HDF5
| Característica | Zarr | HDF5 |
|---|---|---|
| Modelo de almacenamiento | Clave-valor (directorio/objeto) | Archivo binario único |
| Nativo en la nube | Sí — los trozos son objetos independientes | No — requiere descarga completa o SWMR |
| Escrituras paralelas | Sí (sin bloqueo de archivos) | Limitado (HDF5 paralelo requiere MPI) |
| Acceso remoto | Solicitudes HTTP/S3 directas por trozo | Necesita archivo completo o servidor especial |
| Metadatos de formato | JSON (.zarray, .zattrs) | Binario (incrustado en el archivo) |
Consejos Prácticos
- Adapta la forma del trozo al patrón de acceso — la misma regla que en HDF5: la forma del trozo determina la eficiencia de E/S
- Para almacenamiento en la nube: establece el tamaño del trozo en 1–20 MB para equilibrar la sobrecarga de solicitudes GET vs. lectura excesiva de datos
- Usa xarray como interfaz principal —
xr.open_zarr()añade etiquetas de coordenadas, metadatos CF e integración con Dask en un solo paso - Consolida los metadatos antes de publicar:
zarr.consolidate_metadata('conjunto_datos.zarr')escribe todos los.zarray/.zattrsen un único.zmetadataJSON - Zarr no es una base de datos — no tiene transacciones ni actualizaciones de trozos parciales; úsalo para patrones de escritura única o solo de anexado
El modelo de almacenamiento fragmentado nativo en la nube de Zarr lo convierte en el formato de elección para datos científicos que deben accederse a escala desde almacenamiento de objetos — el sucesor de HDF5 para la era de la computación en la nube.
Conversiones relacionadas
Conversiones frecuentes del catálogo: