Dodawanie kompresji do pliku NetCDF przy użyciu xarray

Oct 23 2020

Mam raster, który próbuję skompresować i przekonwertować na NetCDFformat z poziomem kompresji = 9 przy użyciu xarraypakietu. Zakładam, że kompresja jest dodawana za pomocą parametru kodowania jako dykta, ale nie jestem do końca pewien, jak rozumiem, co tu w całości dodać:

 f = directory + "/D_Passaic_F02_NBR_E0001_WGS84_comp"
 t = xarray.open_rasterio(f)
 encode = {'zlib': True, 'complevel': 9}
 t.to_netcdf(output_dir+"/Test2.nc", encoding=encode)

Zasadniczo pojawia się błąd: KeyError: 'zlib'ale nie jestem pewien, czego mam tutaj użyć. Propozycje? Tablica danych przedstawia pojedyncze pasmo oraz zmienne x i y w następujący sposób:

 <xarray.DataArray (band: 1, y: 9635, x: 14564)>  

        or, in more detail:

 <bound method ImplementsArrayReduce._reduce_method.<locals>.wrapped_func of 
 <xarray.DataArray (band: 1, y: 9635, x: 14564)>
 [140324140 values with dtype=float32]
 Coordinates:
   * band     (band) int32 1
   * y        (y) float64 41.06 41.06 41.06 41.06 ... 40.74 40.74 40.74 40.74
   * x        (x) float64 -74.45 -74.45 -74.45 -74.45 ... -73.97 -73.97 -73.97
 Attributes:
     transform:                 (3.2670488250568696e-05, 0.0, -74.447024371179...
     crs:                       +init=epsg:4326
     res:                       (3.2670488250568696e-05, 3.2670488250568696e-05)
     is_tiled:                  1
     nodatavals:                (-9999.0,)
     scales:                    (1.0,)
     offsets:                   (0.0,)
     AREA_OR_POINT:             Area
     HISTOGRAM:                 9090|9307|9097|9209|8729|8864|8744|8864|9181|9...
     TIFFTAG_ARTIST:            HEC-RAS
     TIFFTAG_IMAGEDESCRIPTION:  Depth (Max)>

Odpowiedzi

2 bugmenot123 Oct 23 2020 at 03:14

Błąd wskazuje, że xarray próbuje znaleźć zmienną o nazwie „zlib” w Twoich danych. Prawidłowa struktura dyktowania kodowania wyglądałaby następująco:

encode = {"precipitation": {'zlib': True, ...}}

Jednak ze względu na sposób wczytywania danych jest to trudne.

To, co masz po załadowaniu pliku za pomocą, open_rasterioto plik DataArray. A DataArraynie ma struktury ze zmiennymi. Pisząc do NetCDF, Twoje dane muszą mieć rozszerzenie DataSet.

Jeśli wywołasz to_netcdfa DataArray, automatycznie wygeneruje DataSetzmienną dla danych o nazwie „ __xarray_dataarray_variable__”. Więc to zadziała, ale wynikowy plik będzie brzydki i będzie miał taką nazwę ...:

encode = {"__xarray_dataarray_variable__": {'zlib': True, ...}}  # yuck!

Podczas ręcznego tworzenia zestawu danych można określić nazwę zmiennej. Na przykład, jeśli Twój zespół zawiera dane DEM, coś takiego może mieć sens:

dem = t.to_dataset(name="dem")

Następnie możesz określić dyktowanie kodowania i uzyskać rozsądną nazwę w wyniku:

encoding = {"dem": {'zlib': True, ...}}
dem.to_netcdf("dem.nc", encoding=encoding)

Niestety, kompresja za pomocą xarray jest bardzo wymagająca dla pamięci RAM, uważaj na niezapisaną pracę przed jej uruchomieniem na wypadek, gdyby twój system OOM był.

Bibliografia:

  • https://xarray.pydata.org/en/stable/generated/xarray.open_rasterio.html
  • https://xarray.pydata.org/en/stable/generated/xarray.DataArray.to_netcdf.html#xarray.DataArray.to_netcdf
  • https://xarray.pydata.org/en/stable/generated/xarray.Dataset.to_netcdf.html