たくさんの HDF5 ファイルがあります。基本的に、それぞれが特定の月に〜1度の解像度でグローバルマップを持っています。期間全体をカバーする xarray データセットを作成したいと考えています。ただし、一部の HDF5 ファイルは空です (たとえば、特定の月にデータがありません)。
これを行う最善の方法は何ですか?私はそれが機能すると思っていxr.open_mfdatasetましたが、これは機能しません (おそらく、HDF5 には緯度/経度の「偽の」変数があるため)。サブデータセットに rasterio を使用すると、次のような作業が必要になります。
def read_month(fname):
ds = xr.open_rasterio(f'HDF5:"{fname}"://layer', chunks={"band":1})
return ds
da = xr.concat([read_month(f) for f in fnames],
dim="band", coords={"band":times}
)
fnames上記は空のファイルを完全に見逃しており、コードは正しい構造を読み取りますが、リーダーは地理参照またはタイミング情報を解釈しません。
<xarray.DataArray (band: 19, y: 180, x: 360)>
dask.array<concatenate, shape=(19, 180, 360), dtype=float64, chunksize=(1, 180, 360), chunktype=numpy.ndarray>
Coordinates:
* band (band) int64 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
* y (y) float64 0.5 1.5 2.5 3.5 4.5 ... 175.5 176.5 177.5 178.5 179.5
* x (x) float64 0.5 1.5 2.5 3.5 4.5 ... 355.5 356.5 357.5 358.5 359.5
Attributes:
transform: (1.0, 0.0, 0.0, 0.0, 1.0, 0.0)
res: (1.0, -1.0)
is_tiled: 0
nodatavals: (0.0,)
scales: (1.0,)
offsets: (0.0,)
アップデート
hdf5netcdf をインストールし、以下のようにデータを読み込もうとしました (基本的に、CF データをデコードしようとせず、「偽の薄暗い」を処理します)。次に、仮の次元の名前を変更し、緯度を反転する必要があります。
fnames = sorted([f for f in Path("/somewhere/over/the/rainbow").glob("nightmare*h5") if f.stat().st_size > 10500])
dates = pd.to_datetime([f.name.split(".")[-2] for f in fnames], format="%Y%j")
for fname in fnames:
xds = xr.open_dataset(fname, chunks={},
engine="h5netcdf",
backend_kwargs = {"phony_dims":"access"},
decode_cf=False
)
xds = xds.swap_dims({"phony_dim_0":"lat", "phony_dim_1":"lon"}
).assign_coords({"lat":np.linspace(90, -90, 180)})
ss.append(xds)
da=xr.concat(ss, dates)
da = da.swap_dims({"concat_dim":"time"})
私が見る限り、これは問題なく動作しますが、ハックであり、完了するまでに長い時間がかかります。これで netcdf ファイルとして保存できると思いますが、これが正しい方法かどうかを確認できるとよいでしょう。