¿h5py no cumple con las especificaciones de fragmentación?

Problema: Tengo archivos netCDF4 existentes (aproximadamente 5000 de ellos), (típicamente en forma 96x3712x3712) puntos de datos (float32). Estos son archivos con la primera dimensión siendo el tiempo (1 archivo por día), la segunda y la tercera dimensión espacial. Actualmente, realizar un corte sobre la primera dimensión (incluso un corte parcial) tomaría mucho tiempo debido a las siguientes razones:

los archivos netCDF se fragmentan con un tamaño de fragmento de 1x3712x3712. Cortar la dimensión del tiempo básicamente leería todo el archivo.el bucle (incluso en múltiples procesos) sobre todos los archivos más pequeños también llevaría mucho tiempo.

Mi meta:

crear archivos de datos mensuales (aproximadamente 2900x3712x3712) puntos de datosoptimizarlos para cortar en dimensión de tiempo (tamaño de fragmento de 2900x1x1 o ligeramente mayor en las dimensiones espaciales)

Otros requerimientos:

los archivos deben poder agregarse con una sola marca de tiempo (1x3712x3712), y este proceso de actualización debe tomar menos de 15 minutosla consulta debe ser lo suficientemente rápida: un segmento completo a lo largo del tiempo en menos de un segundo (es decir, 2900x1x1) ==> no hay tantos datos de hecho ...preferiblemente, los archivos deben ser accesibles para que sean leídos por múltiples procesos mientras se actualizanprocesar los datos históricos (los otros 5000 archivos diarios) debería tomar menos de un par de semanas preferiblemente.

Ya probé varios enfoques:

concatenar archivos netcdf y volver a juntarlos ==> toma demasiada memoria y demasiado tiempo ...escribirlos desde pandas a un archivo hdf (usando pytables) ==> crea una tabla amplia con un índice enorme. Eventualmente, esto también tomará demasiado tiempo para leer y requiere que el conjunto de datos esté en mosaico sobre las dimensiones espaciales debido a restricciones de metadatos.mi último enfoque fue escribirlos en un archivo hdf5 usando h5py:

Aquí está el código para crear un solo archivo mensual:

import h5py
import pandas as pd
import numpy as np

def create_h5(fps):
    timestamps=pd.date_range("20050101",periods=31*96,freq='15T') #Reference time period
    output_fp = r'/data/test.h5'
    try:
        f = h5py.File(output_fp, 'a',libver='latest')
        shape = 96*nodays, 3712, 3712
        d = f.create_dataset('variable', shape=(1,3712,3712), maxshape=(None,3712,3712),dtype='f', compression='gzip', compression_opts=9,chunks=(1,29,29))
        f.swmr_mode = True
        for fp in fps:
            try:
                nc=Dataset(fp)
                times = num2date(nc.variables['time'][:], nc.variables['time'].units)
                indices=np.searchsorted(timestamps, times)
                for j,time in enumerate(times):
                    logger.debug("File: {}, timestamp: {:%Y%m%d %H:%M}, pos: {}, new_pos: {}".format(os.path.basename(fp),time,j,indices[j]))
                    d.resize((indices[j]+1,shape[1],shape[2]))
                    d[indices[j]]=nc.variables['variable'][j:j+1]
                    f.flush()
            finally:
                nc.close()
    finally:
        f.close()
    return output_fp

Estoy usando la última versión de HDF5 para tener la opción SWMR. El argumento fps es una lista de rutas de archivos de los archivos diarios netCDF4. Crea el archivo (en un ssd, pero veo que la creación del archivo está principalmente vinculada a la CPU) en aproximadamente 2 horas, lo cual es aceptable.

Tengo la compresión configurada para mantener el tamaño del archivo dentro de los límites. Hice pruebas anteriores sin, y vi que la creación sin es un poco más rápida, pero el corte no lleva mucho más tiempo con la compresión. H5py fragmenta automáticamente el conjunto de datos en fragmentos 1x116x116.

Ahora el problema: cortar en un NAS con la configuración RAID 6, toma unos 20 segundos para cortar la dimensión de tiempo, a pesar de que está en un solo fragmento ...

Me imagino que, aunque está en un solo fragmento en el archivo, porque escribí todos los valores en un bucle, debe fragmentarse de alguna manera (aunque no sé cómo funciona este proceso). Es por eso que intenté hacer un paquete h5 usando las herramientas CML de HDF5 en un nuevo archivo, con los mismos fragmentos pero con suerte reordenando los valores para que la consulta pueda leer los valores en un orden más secuencial, pero no tuve suerte. Aunque este proceso tardó 6 horas en ejecutarse, no hizo nada en la velocidad de consulta.

Si hago mis cálculos correctamente, leer un fragmento (2976x32x32) solo tiene unos pocos MB (11 MB sin comprimir, solo un poco más de 1 MB comprimido, creo). ¿Cómo puede llevar tanto tiempo? ¿Qué estoy haciendo mal? Me alegraría si alguien puede arrojar luz sobre lo que realmente está sucediendo detrás de escena ...

Respuestas a la pregunta(1)

Su respuesta a la pregunta