13:43 15.05.2015
В данном сообщении будет показано как представить ифнормацию о времени из файлов netcdf в наглядном виде.
Обычно время (time) является одним из самых востребованных измерений (dimension) при работе с netcdf файлами. Удобно именно время делать осью без ограничений по длине (unlimited). Но в отличие от переменных (солёность, температура, давление и др.), формат времени по умолчанию далёк от привычного ГОД-МЕСЯЦ-ДЕНЬ-ЧАС-МИН-СЕК.
В netcdf отсчёты времени ведутся от некоторой довольно далёкой от нас даты, в примере это будет 1800 год. Шаг по времени зависит от временного разрешения данных, в примере это 1 час. Обычное значение переменной времени выглядит примерно так: 1498761. Сразу непонятно какая именно это дата.
Для преобразования временного формата из файла netcdf воспользуемся модулем netCDF4, а именно функцией num2date из него. Эта функция берёт на вход массив значений времени t и параметр units, который представляет собой строку. Информацию об этой строке можно взять прямо из файла с помощью метода units, который есть у ПЕРЕМЕННОЙ "Время" (times).
В качестве исходного netcdf файла был взят файл формата netcdf4 из реанализа NCEP/NCAR I.
Электронные ресурсы:
+Описание модуля datetime.
Ключевые слова: #python, #scipy, #datetime, #netcdftime, #netcdf
import os
import numpy as np
from matplotlib import rcParams
import netCDF4 as nc
from netCDF4 import num2date
pwd = os.getcwd()
os.chdir(u'D://NCDATA//ncep_ncar_I//monthly//')
print pwd
param = 'hgt'
fname = 'mon.mean.nc'
ncname = '%s.%s' % (param, fname)
ncfile = nc.Dataset(ncname, 'r')
os.chdir(pwd)
# ****************************************
# Это переменная "Время"
times = ncfile.variables['time']
# Это значения переменной "Время"
t = ncfile.variables['time'][:]
v = ncfile.variables[param][:]
print(ncfile.variables[param])
print(ncfile.variables['time'])
dates = num2date(times[:], units=times.units)
print (u'Тип массива dates %s' % type(dates[0]))
for i in range(10):
print ('%d %s' % (i, dates[i]))
i = 0
print (u'Временная запись N %d:' % (i))
print ('----------------------')
print (u'Год %d' % dates[i].year)
print (u'Месяц %d' % dates[i].month)
print (u'День %d' % dates[i].day)
print (u'Час %d' % dates[i].hour)
print (u'Секунда %d' % dates[i].second)
C:\Users\SHABA\Documents\GitHub\rus_numpy_scipy <type 'netCDF4.Variable'> float32 hgt(time, level, lat, lon) long_name: Monthly mean geopotential height valid_range: [ -700. 35000.] units: m add_offset: 0.0 scale_factor: 1.0 missing_value: -9.96921e+36 precision: 0 least_significant_digit: 0 GRIB_id: 7 GRIB_name: HGT var_desc: Geopotential height dataset: CDC Derived NCEP Reanalysis Products level_desc: Multiple levels statistic: Mean parent_stat: Other actual_range: [ -334.5161438 32321.09765625] unlimited dimensions: time current shape = (804, 17, 73, 144) filling on, default _FillValue of 9.96920996839e+36 used <type 'netCDF4.Variable'> float64 time(time) long_name: Time delta_t: 0000-01-00 00:00:00 avg_period: 0000-01-00 00:00:00 prev_avg_period: 0000-00-01 00:00:00 standard_name: time axis: T units: hours since 1800-01-01 00:00:0.0 actual_range: [ 1297320. 1883904.] unlimited dimensions: time current shape = (804,) filling on, default _FillValue of 9.96920996839e+36 used Тип массива dates <type 'datetime.datetime'> 0 1948-01-01 00:00:00 1 1948-02-01 00:00:00 2 1948-03-01 00:00:00 3 1948-04-01 00:00:00 4 1948-05-01 00:00:00 5 1948-06-01 00:00:00 6 1948-07-01 00:00:00 7 1948-08-01 00:00:00 8 1948-09-01 00:00:00 9 1948-10-01 00:00:00 Временная запись N 0: ---------------------- Год 1948 Месяц 1 День 1 Час 0 Секунда 0
Функция num2date возвращает список, состоящий из объектов типа datetime.datetime, у котрого есть методы year, month, dat, hour, second. Обращаясь к каждой записи datetime с соответствующим методом можно получить представление даты в наглядном виде - в виде числа или строки.
Оформив часть кода в виде функции можно автоматизированно переводить время из внутреннего формата netcdf в удобный пользователю вид. Например, это можно сделать так:
import os
import numpy as np
from matplotlib import rcParams
import netCDF4 as nc
from netCDF4 import num2date
def date2arr(date):
year = int(date.year)
month = int(date.month)
day = int(date.day)
dlist = [year, month, day]
return dlist
pwd = os.getcwd()
os.chdir(u'D://NCDATA//ncep_ncar_I//monthly//')
print pwd
param = 'hgt'
fname = 'mon.mean.nc'
ncname = '%s.%s' % (param, fname)
ncfile = nc.Dataset(ncname, 'r')
os.chdir(pwd)
# ****************************************
# Это переменная "Время"
times = ncfile.variables['time']
# Это значения переменной "Время"
t = ncfile.variables['time'][:]
print(ncfile.variables['time'])
dates = num2date(times[:], units=times.units)
figs = map(date2arr, dates)
figs = np.array(figs, dtype='int')
print (np.shape(figs))
print u'Первый год', figs[0, 0]
print u'Последний год', figs[-1, 0]
print figs[0:20]
C:\Users\SHABA\Documents\GitHub\rus_numpy_scipy <type 'netCDF4.Variable'> float64 time(time) long_name: Time delta_t: 0000-01-00 00:00:00 avg_period: 0000-01-00 00:00:00 prev_avg_period: 0000-00-01 00:00:00 standard_name: time axis: T units: hours since 1800-01-01 00:00:0.0 actual_range: [ 1297320. 1883904.] unlimited dimensions: time current shape = (804,) filling on, default _FillValue of 9.96920996839e+36 used (804L, 3L) [[1948 1 1] [1948 2 1] [1948 3 1] [1948 4 1] [1948 5 1] [1948 6 1] [1948 7 1] [1948 8 1] [1948 9 1] [1948 10 1] [1948 11 1] [1948 12 1] [1949 1 1] [1949 2 1] [1949 3 1] [1949 4 1] [1949 5 1] [1949 6 1] [1949 7 1] [1949 8 1]] Первый год 1948 Последний год 2014
Таким образом, дата 1498761 из примера выше - это 09:00 24.12.1970. Просто и наглядно.
from netCDF4 import num2date
units = 'hours since 1800-01-01 00:00:0.0'
idate = num2date(1498761, units)
print str(idate)
1970-12-24 09:00:00