将多个 NetCDF 文件组合成时间序列多维数组 python
Combine multiple NetCDF files into timeseries multidimensional array python
我正在使用来自多个 netcdf 文件(在我计算机上的一个文件夹中)的数据。每个文件保存整个美国的数据,为期 5 年。位置是根据 x 和 y 坐标的索引引用的。我正在尝试为多个位置(网格单元)创建时间序列,将 5 年期间编译为 20 年期间(这将合并 4 个文件)。现在我能够从一个位置的所有文件中提取数据,并使用 numpy append 将其编译成一个数组。但是,我想提取多个位置的数据,将其放入一个矩阵中,其中行是位置,列包含时间序列降水数据。我想我必须创建一个列表或字典,但我不太确定如何在循环中将数据分配给 list/dictionary。
我是 python 和 netCDF 的新手,如果这是一个简单的解决方案,请原谅我。我一直在使用这段代码作为指南,但还没有想出如何根据我想做的事情格式化它:Python Reading Multiple NetCDF Rainfall files of variable size
这是我的代码:
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 个文件放在保管箱中以便您可以访问它们,但我只允许 post 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
不错的开始,我会推荐以下内容来帮助您解决问题。
首先,查看 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 等。
您可以使用 Python 中的 netCDF4
包轻松地将多个 netCDF 文件合并为一个文件。请参阅下面的示例:
我有四个 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'])
与 N1B4 的答案并行,您还可以从命令行使用 CDO 沿时间维度连接 4 个文件
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
这会挑选出最接近您指定的 lon/lat (X,Y) 坐标的网格单元,或者您可以根据需要使用双线性插值法:
cdo remapbil,lon=X/lat=Y merged_file.nc my_location.nc
我更喜欢xarray的方法
ds = xr.open_mfdataset('nc_*.nc', combine = 'by_coord', concat_dim = 'time')
ds.to_netcdf('nc_combined.nc') # Export netcdf file
我正在使用来自多个 netcdf 文件(在我计算机上的一个文件夹中)的数据。每个文件保存整个美国的数据,为期 5 年。位置是根据 x 和 y 坐标的索引引用的。我正在尝试为多个位置(网格单元)创建时间序列,将 5 年期间编译为 20 年期间(这将合并 4 个文件)。现在我能够从一个位置的所有文件中提取数据,并使用 numpy append 将其编译成一个数组。但是,我想提取多个位置的数据,将其放入一个矩阵中,其中行是位置,列包含时间序列降水数据。我想我必须创建一个列表或字典,但我不太确定如何在循环中将数据分配给 list/dictionary。
我是 python 和 netCDF 的新手,如果这是一个简单的解决方案,请原谅我。我一直在使用这段代码作为指南,但还没有想出如何根据我想做的事情格式化它:Python Reading Multiple NetCDF Rainfall files of variable size
这是我的代码:
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 个文件放在保管箱中以便您可以访问它们,但我只允许 post 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
不错的开始,我会推荐以下内容来帮助您解决问题。
首先,查看 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 等。
您可以使用 Python 中的 netCDF4
包轻松地将多个 netCDF 文件合并为一个文件。请参阅下面的示例:
我有四个 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'])
与 N1B4 的答案并行,您还可以从命令行使用 CDO 沿时间维度连接 4 个文件
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
这会挑选出最接近您指定的 lon/lat (X,Y) 坐标的网格单元,或者您可以根据需要使用双线性插值法:
cdo remapbil,lon=X/lat=Y merged_file.nc my_location.nc
我更喜欢xarray的方法
ds = xr.open_mfdataset('nc_*.nc', combine = 'by_coord', concat_dim = 'time')
ds.to_netcdf('nc_combined.nc') # Export netcdf file