netCDF4ファイルの設定によっては、ファイルを読み込んでもすべてnanになることがあります。その原因と対処法を備忘録として残しておきます。
スポンサーリンク
netCDF4ファイル設定の例と原因
例えば「ncdump -c test.nc」としたときに以下のように表示される架空のnetCDF4ファイルがあったとします。
このままでは、printしてもnan値(すべて「-----」)になってしまいます。
dimensions:
time = UNLIMITED ; // (85 currently)
latitude = 180 ;
longitude = 360 ;
variables:
short test_value(time, latitude, longitude) ;
test_value:add_offset = 0.f ;
test_value:long_name = "test_value" ;
test_value:scale_factor = 0.033f ;
test_value:units = "ng" ;
test_value:valid_min = -3.f ;
test_value:valid_max = 3.3333f ;
float latitude(latitude) ;
latitude:units = "degrees_north" ;
float longitude(longitude) ;
longitude:units = "degrees_east" ;
int time(time) ;
time:units = "year" ;
// global attributes:
:title = "Test for NetCDF4-Python" ;
:description = "Test for NetCDF-Python as case valid_max and valid_min" ;
:history = "Processed by Lato." ;
原因は「valid_min」と「valid_max」です!これらが設定されている場合、この範囲外の数値はnetCDF4-pythonの仕様によりnanになってしまうようです。逆にこれらの値が設定されていなければnan値が表示されることはありません。
原因については以下のサイトが詳しいです。
対処:nanになるマスクを外す
タイトルの通りです。以下のPythonコードのように、np.whereを使ってマスクを外します。
from netCDF4 import Dataset
import numpy as np
#filei0は対象のnetcdfファイルのパス
nc0 = Dataset(filei0,'r', format='NETCDF4')
latitude = nc0.variables['latitude'][:]
latitude_units = nc0.variables['latitude'].units
longitude = nc0.variables['longitude'][:]
longitude_units = nc0.variables['longitude'].units
time = nc0.variables['time'][:]
time_units = nc0.variables['time'].units
scale_factor0 = nc0.variables['ocean_conc'].scale_factor
#scale_factorを掛けた上でmaskを解除しないと真の値が表示されないので注意
data = nc0.variables['test_value'][:,:,:,:]
var0 = scale_factor0*np.where(data.mask==True, data, data)
#テスト用
print(var0)