Объедините несколько файлов NetCDF в многомерный массив временных рядов Python
Я использую данные из нескольких файлов netcdf (в папке на моем компьютере). Каждый файл содержит данные по всей территории США за период в 5 лет. Ссылки на местоположения основаны на индексе координат x и y. Я пытаюсь создать временной ряд для нескольких местоположений (ячеек сетки), объединяя 5-летние периоды в 20-летний (это будет объединять 4 файла). Прямо сейчас я могу извлечь данные из всех файлов для одного места и скомпилировать их в массив, используя numpy append. Тем не менее, я хотел бы извлечь данные для нескольких местоположений, поместив их в матрицу, где строки - это местоположения, а столбцы содержат данные об осадках временного ряда. Я думаю, что мне нужно создать список или словарь, но я не совсем уверен, как распределить данные для списка / словаря в цикле.
Я новичок в Python и NetCDF, так что простите, если это простое решение. Я использовал этот код в качестве руководства, но не выяснил, как отформатировать его для того, что я хотел бы сделать: Python Чтение нескольких файлов NetCDF Rainfall переменного размера
Вот мой код:
import glob
from netCDF4 import Dataset
import numpy as np
# Define x & y index for grid cell of interest
# Pittsburgh is 37,89
yindex = 37 #first number
xindex = 89 #second number
# Path
path = '/Users/LMC/Research Data/NARCCAP/'
folder = 'MM5I_ccsm/'
## load data file names
all_files = glob.glob(path + folder+'*.nc')
all_files.sort()
## initialize np arrays of timeperiods and locations
yindexlist = [yindex,'38','39'] # y indices for all grid cells of interest
xindexlist = [xindex,xindex,xindex] # x indices for all grid cells of interest
ngridcell = len(yindexlist)
ntimestep = 58400 # This is for 4 files of 14600 timesteps
## Initialize np array
timeseries_per_gridcell = np.empty(0)
## START LOOP FOR FILE IMPORT
for timestep, datafile in enumerate(all_files):
fh = Dataset(datafile,mode='r')
days = fh.variables['time'][:]
lons = fh.variables['lon'][:]
lats = fh.variables['lat'][:]
precip = fh.variables['pr'][:]
for i in range(1):
timeseries_per_gridcell = np.append(timeseries_per_gridcell,precip[:,yindexlist[i],xindexlist[i]]*10800)
fh.close()
print timeseries_per_gridcell
Я поместил 3 файла в Dropbox, чтобы вы могли получить к ним доступ, но мне разрешено публиковать только 2 ссылки. Вот они:
https://www.dropbox.com/s/rso0hce8bq7yi2h/pr_MM5I_ccsm_2041010103.nc?dl=0 https://www.dropbox.com/s/j56undjvv7iph0f/pr_MM5I_ccsm_2046010103.nc?dl=0
5 ответов
Хорошее начало, я бы порекомендовал следующее, чтобы помочь решить ваши проблемы.
Во-первых, посмотрите ncrcat, чтобы быстро объединить ваши отдельные файлы netCDF в один файл. Я настоятельно рекомендую скачать NCO для манипуляций с netCDF, особенно в этом случае, когда это облегчит ваше кодирование Python в дальнейшем.
Допустим, файлы названы precip_1.nc
, precip_2.nc
, precip_3.nc,
а также precip_4.nc
, Вы можете объединить их вдоль размера записи, чтобы сформировать новый precip_all.nc
с рекордным размером длины 58400 с
ncrcat precip_1.nc precip_2.nc precip_3.nc precip_4.nc -O precip_all.nc
В Python нам просто нужно прочитать этот новый отдельный файл, а затем извлечь и сохранить временные ряды для нужных ячеек сетки. Что-то вроде этого:
import netCDF4
import numpy as np
yindexlist = [1,2,3]
xindexlist = [4,5,6]
ngridcell = len(xidx)
ntimestep = 58400
# Define an empty 2D array to store time series of precip for a set of grid cells
timeseries_per_grid_cell = np.zeros([ngridcell, ntimestep])
ncfile = netCDF4.Dataset('path/to/file/precip_all.nc', 'r')
# Note that precip is 3D, so need to read in all dimensions
precip = ncfile.variables['precip'][:,:,:]
for i in range(ngridcell):
timeseries_per_grid_cell[i,:] = precip[:, yindexlist[i], xindexlist[i]]
ncfile.close()
Если вам нужно использовать только Python, вам необходимо отслеживать фрагменты временных индексов, которые формируются отдельными файлами для создания полного временного ряда. 58400/4 = 14600 временных шагов на файл. Таким образом, у вас будет еще один цикл для чтения в каждом отдельном файле и сохранения соответствующего фрагмента времени, т.е. первый файл будет заполнен 0-14599, второй 14600-29199 и т. Д.
Вы можете легко объединить несколько файлов netCDF в один, используя netCDF4
пакет в Python. Смотрите пример ниже:
У меня есть четыре файла netCDF, таких как 1.nc, 2.nc, 3.nc, 4.nc. Используя команду ниже, все четыре файла будут объединены в один набор данных.
import netCDF4
from netCDF4 import Dataset
dataset = netCDF4.MFDataset(['1.nc','2.nc','3.nc','4.nc'])
Я предпочитаю подход xarray
ds = xr.open_mfdataset('nc_*.nc', combine = 'by_coord', concat_dim = 'time')
ds.to_netcdf('nc_combined.nc') # Export netcdf file
Параллельно с ответом N1B4 вы также можете объединить 4 файла по их временному измерению, используя CDO из командной строки.
cdo mergetime precip1.nc precip2.nc precip3.nc precip4.nc merged_file.nc
или с подстановочными знаками
cdo mergetime precip?.nc merged_file.nc
а затем продолжайте читать его в соответствии с этим ответом.
Вы можете добавить еще один шаг из командной строки, чтобы извлечь выбранное местоположение, используя
cdo remapnn,lon=X/lat=Y merged_file.nc my_location.nc
это выбирает ячейку сетки, ближайшую к вашей указанной координате долгота / широта (X,Y), или вы можете использовать билинейную интерполяцию, если хотите:
cdo remapbil,lon=X/lat=Y merged_file.nc my_location.nc
open_mfdatase должен использовать библиотеку DASK для работы. Итак, если по какой-то причине вы не можете использовать его, как я не могу, то этот метод бесполезен.