Hinzufügen einer Komprimierung zu einer NetCDF-Datei mit xarray

Oct 23 2020

Ich habe ein Raster, das ich NetCDFmit dem xarrayPaket komprimieren und in ein Format mit der Komprimierungsstufe = 9 konvertieren möchte. Ich gehe davon aus, dass die Komprimierung mithilfe des Codierungsparameters als Diktat hinzugefügt wird, bin mir aber nicht ganz sicher, wie ich verstehe, was hier vollständig hinzugefügt werden soll:

 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)

Grundsätzlich wird eine Fehlermeldung angezeigt: KeyError: 'zlib'Ich bin mir jedoch nicht sicher, was ich hier verwenden soll. Vorschläge? Das Datenarray zeigt ein einzelnes Band und eine x- und y-Variable wie folgt:

 <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)>

Antworten

2 bugmenot123 Oct 23 2020 at 03:14

Der Fehler weist darauf hin, dass xarray versucht, eine Variable namens "zlib" in Ihren Daten zu finden. Die richtige Struktur für das Codierungsdiktat wäre ungefähr so:

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

Aufgrund der Art und Weise, wie die Daten geladen wurden, ist dies jedoch schwierig.

Was Sie nach dem Laden einer Datei mit haben, open_rasterioist a DataArray. A DataArrayhat keine Struktur mit Variablen. Beim Schreiben in NetCDF müssen Ihre Daten a sein DataSet.

Wenn Sie rufen to_netcdfauf ein DataArray, wird automatisch ein erzeugen DataSetmit einer Variablen für die „genannten Daten __xarray_dataarray_variable__“. Das wird also funktionieren, aber die resultierende Datei wird mit einem solchen Namen hässlich sein ...:

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

Wenn Sie ein DataSet manuell erstellt haben, können Sie den Variablennamen angeben. Wenn Ihre Band beispielsweise DEM-Daten enthält, kann Folgendes sinnvoll sein:

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

Anschließend können Sie das Codierungsdiktat dafür angeben und einen angemessenen Namen im Ergebnis haben:

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

Leider ist die Komprimierung mit xarray sehr RAM-hungrig. Achten Sie auf Ihre nicht gespeicherte Arbeit, bevor Sie sie ausführen, falls Ihr System OOMs hat.

Verweise:

  • 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