Объедините несколько файлов 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 для работы. Итак, если по какой-то причине вы не можете использовать его, как я не могу, то этот метод бесполезен.

Другие вопросы по тегам