Я изо всех сил пытаюсь справиться с этим.
Я создаю файл netcdf4 со следующими размерами и переменными (обратите внимание, в частности, на неограниченный размер point
):
dimensions:
point = UNLIMITED ; // (275935 currently)
realization = 24 ;
variables:
short mod_hs(realization, point) ;
mod_hs:scale_factor = 0.01 ;
short mod_ws(realization, point) ;
mod_ws:scale_factor = 0.01 ;
short obs_hs(point) ;
obs_hs:scale_factor = 0.01 ;
short obs_ws(point) ;
obs_ws:scale_factor = 0.01 ;
short fchr(point) ;
float obs_lat(point) ;
float obs_lon(point) ;
double obs_datetime(point) ;
}
У меня есть программа Python, которая заполняет этот файл данными в цикле (отсюда и неограниченный размер записи - я априори не знаю, насколько большим будет файл).
После заполнения файла его размер составляет 103 МБ.
Моя проблема в том, что чтение данных из этого файла происходит довольно медленно. Я догадался, что это как-то связано с чанкингом и неограниченным point
измерением?
Я запустил ncks --fix_rec_dmn
для файла, и (после долгой обработки) он создал новый файл netCDF размером всего 32 МБ (что примерно соответствует размеру содержащихся в нем данных).
Это огромная разница в размере - почему исходный файл такой раздутый? Кроме того, доступ к данным в этом файле на несколько порядков быстрее. Например, в Python чтение содержимого переменной hs
занимает 2 секунды в исходном файле и 40 миллисекунд в файле с фиксированным размером записи.
Моя проблема заключается в том, что некоторые из моих файлов содержат много точек и кажутся слишком большими для запуска ncks
(на моей машине заканчивается память, а у меня 8 ГБ), поэтому я не могу преобразовать все данные в фиксированную запись. измерение.
Может ли кто-нибудь объяснить, почему размеры файлов такие разные и как я могу сделать исходные файлы меньше и эффективнее для чтения?
Кстати, я не использую сжатие zlib (я выбрал масштабирование значений с плавающей запятой до целого числа).
Крис
РЕДАКТИРОВАТЬ Мой код Python, по сути, создает один файл временных рядов совмещенных моделей и данных наблюдений из нескольких файлов прогнозов отдельных моделей за 3 месяца. Моя модель прогноза запускается 4 раза в день, и я собираю данные за 3 месяца, так что получается ~120 файлов.
Программа извлекает подмножество прогнозируемого периода из каждого файла (например, T+24h -> T+48h), поэтому объединить файлы не так просто.
Это грубое приближение к тому, что делает мой код (на самом деле он читает/записывает больше переменных, но я просто показываю здесь 2 для ясности):
# Create output file:
dout = nc.Dataset(fn, mode='w', clobber=True, format="NETCDF4")
dout.createDimension('point', size=None)
dout.createDimension('realization', size=24)
for varname in ['mod_hs','mod_ws']:
v = ncd.createVariable(varname, np.short,
dimensions=('point', 'realization'), zlib=False)
v.scale_factor = 0.01
# Cycle over dates
date = <some start start>
end_dat = <some end date>
# Keeo track if record dimension ('point') size:
n = 0
while date < end_date:
din = nc.Dataset("<path to input file>", mode='r')
fchr = din.variables['fchr'][:]
# get mask for specific forecast hour range
m = np.logical_and(fchr >= 24, fchr < 48)
sz = np.count_nonzero(m)
if sz == 0:
continue
dout.variables['mod_hs'][n:n+sz,:] = din.variables['mod_hs'][:][m,:]
dout.variables['mod_ws'][n:n+sz,:] = din.variables['mod_wspd'][:][m,:]
# Increment record dimension count:
n += sz
din.close()
# Goto next file
date += dt.timedelta(hours=6)
dout.close()
Интересно, что если я сделаю формат выходного файла NETCDF3_CLASSIC
, а не NETCDF4
, размер вывода будет таким, как я ожидал. Вывод NETCDF4 кажется раздутым.