Обработка очень больших файлов netCDF на python

Я пытаюсь работать с данными из очень больших файлов netCDF (~ 400 Gb каждый). Каждый файл имеет несколько переменных, все намного больше, чем системная память (например, 180 ГБ против 32 ГБ ОЗУ). Я пытаюсь использовать numpy и netCDF4-python делать некоторые операции над этими переменными, копируя срез за раз и работая на этом срезе. К сожалению, на самом деле требуется очень много времени, чтобы прочитать каждый кусочек, который убивает производительность.

Например, одна из переменных – это массив формы (500, 500, 450, 300) . Я хочу работать на срезе [:,:,0] , поэтому я делаю следующее:

 import netCDF4 as nc f = nc.Dataset('myfile.ncdf','r+') myvar = f.variables['myvar'] myslice = myvar[:,:,0] 

Но последний шаг занимает очень много времени (~ 5 минут в моей системе). Если, например, я сохранил переменную формы (500, 500, 300) в файле netcdf, то операция чтения того же размера займет всего несколько секунд.

Есть ли способ ускорить это? Очевидным путем было бы преобразование массива таким образом, чтобы индексы, которые я выбираю, выходили первым. Но в таком большом файле это невозможно сделать в памяти, и кажется еще медленнее попытаться это сделать, если простая операция уже занимает много времени. Мне бы хотелось, это быстрый способ прочитать фрагмент файла netcdf, используя функцию get_vara интерфейса Fortran. Или какой-то способ эффективного переноса массива.

2 Solutions collect form web for “Обработка очень больших файлов netCDF на python”

Вы можете перенести переменные netCDF слишком большими, чтобы они соответствовали памяти, используя утилиту nccopy, которая описана здесь:

http://www.unidata.ucar.edu/netcdf/docs/guide_nccopy.html

Идея состоит в том, чтобы «переписать» файл, указав, какие формы кусков (многомерных плит) вы хотите для переменных. Вы можете указать, сколько памяти использовать в качестве буфера и сколько использовать для кеш-фрагментов, но неясно, как оптимально использовать память между этими использованиями, поэтому вам, возможно, придется просто попробовать несколько примеров и время их. Вместо того, чтобы полностью переносить переменную, вы, вероятно, захотите «частично перенести» ее, указав куски, которые содержат много данных по двум большим размерам вашего среза и имеют только несколько значений по другим измерениям.

Это комментарий, а не ответ, но я не могу прокомментировать сказанное, извините.

Я понимаю, что вы хотите обработать myvar[:,:,i] , с i в range(450) . В этом случае вы собираетесь сделать что-то вроде:

 for i in range(450): myslice = myvar[:,:,i] do_something(slice) 

и узким местом является доступ к myslice = myvar[:,:,i] . Вы пытались сравнить время, необходимое для доступа к moreslices = myvar[:,:,0:n] ? Это будут данные contiguos, и, возможно, вы сможете сэкономить время. Вы выбрали бы n размером с памятью, а затем обработали следующий фрагмент данных moreslices = myvar[:,:,n:2n] и так далее.

  • Pyinstaller numpy "Intel MKL FATAL ERROR: Не удается загрузить файл mkl_intel_thread.dll"
  • Окраска только внутренней части формы
  • Изменение масштаба оси в нулевом графике
  • Обнуленная установка numpy - `GFORTRAN_1.4 'не найдена ошибка
  • Вычислить все возможные разности столбцов в матрице
  • Как получить центроиды из иерархической агломерационной кластеризации SciPy?
  • Черное пространство в изображении GLCM
  • Преобразование np.ndarray в np.array в python
  • Python - лучший язык программирования в мире.