背景
netCDFは、多次元データを格納するのに便利な拡張子です。
気象、海洋、気候の世界では広く使われています。
一方で、このデータの課題として、多次元配列が故にファイルサイズが大きくなることが挙げられます。
これにより、データの読み込み時にメモリの使用量が増え、かつ待機時間が伸びることが課題になりがちです。
そこで、今回はnetcdfのファイルサイズを圧縮する方法をお伝えします。
結論
xarray
ライブラリを使います。
公式Documentは以下の通りです。
print(ds) """ <xarray.Dataset> Size: 416B Dimensions: (loc: 2, instrument: 3, time: 4) Coordinates: lon (loc) float64 16B -99.83 -99.32 lat (loc) float64 16B 42.25 42.21 Dimensions without coordinates: loc, instrument, time Data variables: temperature (loc, instrument, time) float64 192B 9.584 18.36 ... 16.99 precipitation (loc, instrument, time) float64 192B 4.323 8.643 ... 1.573 Attributes: description: Weather related data. """ ds.to_netcdf("output.nc", encoding={'temperature':{'dtype': 'int16', "zlib": True, , "complevel": 9}}})
Pointは、
encoding
で、zlib=True
にすること。- 型を与えて不必要以上の型を与えないこと。
float
は、スケールファクターを与えてint
型で保存すると効果はバツグン
です。
軽量化したファイルの書き込み
上記のとおりです。
公式Documentを見ながら、試してみてください。
軽量化したファイルの読み込み
特に変化はありません。
import xarray as xr file = "NC_H08_20161117_0230_B01_JP02_R10.nc" ds = xr.open_dataset(file)
サンプルデータ
xarrayでデータを作る
書き込みが想定されるので、データの作り方も合わせて例示します。
import numpy as np import pandas as pd import xarray as xr temperature = 15 + 8 * np.random.randn(2, 3, 4) precipitation = 10 * np.random.rand(2, 3, 4) lon = [-99.83, -99.32] lat = [42.25, 42.21] instruments = ["manufac1", "manufac2", "manufac3"] time = pd.date_range("2014-09-06", periods=4) reference_time = pd.Timestamp("2014-09-05") ds = xr.Dataset( data_vars=dict( temperature=(["loc", "instrument", "time"], temperature), precipitation=(["loc", "instrument", "time"], precipitation), ), coords=dict( lon=("loc", lon), lat=("loc", lat), ), attrs=dict(description="Weather related data.") ) print(ds)
ナウでヤングな方法は、netcdf4
からxarray
かもしれない(?)