Python NetCDFファイル 読み書きまとめ

本記事では、PythonでNetCDFファイルを読み書きする方法を紹介します。

NetCDFファイルとは

NetCDFとは、バイナリファイルフォーマットの一つであり、その拡張子は”.nc”である。 NetCDFは気象、海洋、気候変動などの分野で国際的に広く使われている。 Wikipedia参照

また、NetCDFファイルは、ncdumpコマンドを使うことで、どのようなデータが格納されているのか調べることができます。

使用するデータ

さっそくコードをNetCDFファイルを読み込むコードを見ていきます。

例では、このような4次元データを読み込んでいます。

netcdf PRES_0020.pe000000 {
dimensions:
        z = 75 ;
        x = 512 ;
        y = 512 ;
        time = UNLIMITED ; // (21 currently)
variables:
        float PRES(time, z, y, x) ;
                PRES:long_name = "pressure" ;
                PRES:units = "Pa" ;
                PRES:standard_name = "air_pressure" ;
                PRES:_FillValue = -9.9999e+30f ;
                PRES:missing_value = -9.9999e+30f ;
                PRES:coordinates = "lon lat height time" ;
                PRES:cell_measures = "volume: cell_volume" ;
                PRES:grid = "grid" ;
                PRES:location = "face" ;

上記の結果は、ncdumpコマンドを用いています。

Pythonでは、netCDF4モジュールとxarrayモジュールを用いた2つの方法があります。

netCDF4モジュールを用いる方法

コード(読み込み)

import netCDF4
import numpy as np

cfile = 'PRES_0020.pe000000.nc'
fnc = netCDF4.Dataset(cfile,'r')
var = fnc.variables['PRES'][:]
xx = fnc.variables['x'][:]
yy = fnc.variables['y'][:]
zz = fnc.variables['z'][:]
tt = fnc.variables['time'][:]

解説

1行目で、netCDF4モジュールをインポートします。

netは、小文字、CDFは、大文字なので注意です。

4行目で、ファイルを読み込みます。1つ目の引数は、読み込むファイルの指定、2つ目の引数は、’r’で読み込み指定しています。

因みに、’w’で書き込み指定になります。

5行目で、varという変数に今回のnetCDFファイルのデータであるPRESというデータを格納します。

PRESは、ncdumpコマンドでvariablesの変数名を指定しましょう。

これだけで、データを読み込むことができます。

以下のコードは、どちらかというと書き込む際に用います。

6行目で、xxという変数にx軸の値を格納します。

7行目で、yyという変数にy軸の値を格納します。

8行目で、zzという変数にz軸の値を格納します。

9行目で、ttという変数に時間軸の値を格納します。

コード(書き込み)

# 続き
ofile = 'out.nc'
out = netCDF4.Dataset(ofile,'w',format = 'NETCDF3_CLASSIC')
out.createDimension('time',None)
out.createDimension('z',zz.size)
out.createDimension('y',yy.size)
out.createDimension('x',xx.size)
nc_time = out.createVariable('time',np.dtype('float32').char,('time',))
nc_time.long_name = 'time'
nc_time.units = 'time'
nc_z = out.createVariable('z',np.dtype('float32').char,('z',))
nc_z.long_name = 'z'
nc_z.units = 'm'
nc_y = out.createVariable('y',np.dtype('float32').char,('y',))
nc_y.long_name = 'y'
nc_y.units = 'm'
nc_x = out.createVariable('x',np.dtype('float32').char,('x',))
nc_x.long_name = 'x'
nc_x.units = 'm'
nc_var = out.createVariable('press',np.dtype('float32').char,('time','z','y','x'))
nc_var.long_name = 'air pressure'
nc_var.units = 'Pa'
nc_time[:] = tt
nc_z[:] = zz
nc_y[:] = yy
nc_x[:] = xx
nc_var[:] = amp_pw
out.close()

解説

3行目で、ファイルを読み込みます。1つ目の引数は、読み込むファイルの指定、2つ目の引数は、’w’で書き込み指定しています。

4~7行目で、次元を作成します。今回は、4次元ですので、4つ作成しています。

1つ目の引数は、次元の名称、2つ目の引数は、次元長を指定します。

8行目以降は変数を作成していきます。

out.createVariableで変数の名称、型、次元を設定します。

nc_*.long_nameは、ncdumpコマンドでの変数の正式な名前を設定します。

nc_*.unitsは、その変数の単位を設定します。

因みに、nc_*.long_nameとnc_*.unitsは、なくても書き出すことは可能です。

23行目~26行目で、作った変数に実際の値を代入しています。

out.close()でファイル操作を終了させましょう。

xarrayモジュールを用いる方法

コード(読み込み)

import xarray as xr

cfile = 'PRES_0020.pe000000.nc'
fnc = xr.open_dataset(cfile)
var = fnc.variables['PRES']
xx = fnc.variables['x']
yy = fnc.variables['y']
zz = fnc.variables['z']
tt = fnc.variables['time']

解説

1行目で、xarrayモジュールをインポートします。

4行目で、ファイルを読み込みます。

5行目で、varという変数に今回のnetCDFファイルのデータであるPRESというデータを格納します。

PRESは、ncdumpコマンドでvariablesの変数名を指定しましょう。

これだけで、データを読み込むことができます。

以下のコードは、どちらかというと書き込む際に用います。

6行目で、xxという変数にx軸の値を格納します。

7行目で、yyという変数にy軸の値を格納します。

8行目で、zzという変数にz軸の値を格納します。

9行目で、ttという変数に時間軸の値を格納します。

コード(書き込み)

#続き
out = xr.DataArray(
    var,
    name = 'press',
    coords = (
        tt,zz,yy,xx,
    ),
    attrs = {
        'long_name' : 'air pressure'
        'units'     : 'Pa'    
    },
)
cofile = "out.nc"
out.to_netcdf(cofile)

解説

xarrayモジュールのDataArrayを用います。

3行目で、実際の値を指定します。今回は、変数varです。

4行目で、変数の名前を指定します。

5~7行目で、coordsの中に変数の次元を指定します。

8~11行目で、ncdumpコマンドでの変数名の正式な名称と単位を指定しています。

8~11行目のattrsは、なくても書き出すことは可能です。

まとめ

PythonでnetCDFファイルを読み込む方法を紹介しました。

netCDF4モジュールよりxarrayモジュールを用いたほうがコード量が少なく済みます。

NetCDFファイルを読み書きする他の方法はこちら