【问题标题】:Combine multiple NetCDF files into timeseries multidimensional array python将多个NetCDF文件组合成时间序列多维数组python
【发布时间】:2015-09-05 22:17:15
【问题描述】:

我正在使用来自多个 netcdf 文件的数据(在我计算机上的一个文件夹中)。每个文件保存整个美国的数据,为期 5 年。基于 x 和 y 坐标的索引来引用位置。我正在尝试为多个位置(网格单元)创建一个时间序列,将 5 年的时间段编译为 20 年的时间段(这将组合 4 个文件)。现在,我能够从一个位置的所有文件中提取数据,并使用 numpy append 将其编译成一个数组。但是,我想提取多个位置的数据,将其放入矩阵中,其中行是位置,列包含时间序列降水数据。我想我必须创建一个列表或字典,但我不确定如何在循环中将数据分配给列表/字典。

我是 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 个文件放在 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

【问题讨论】:

  • 查看 netCDF4-python 包的 MFDataset 类。它会自动将 netCDF 文件组合成 Python 中的单个 netCDF4.MFDataset 对象,并沿时间轴将它们连接起来。
  • @SpencerHill 你能提供一个更新的 MFDataset 链接吗?您提供的链接已损坏。如果它不在您的链接中,任何关于如何使用的提示都会很棒。非常感谢。

标签: python netcdf nco cdo-climate


【解决方案1】:

很好的开始,我会推荐以下内容来帮助您解决问题。

首先,查看ncrcat 以快速将您的各个 netCDF 文件连接到一个文件中。我强烈建议下载 NCO 以进行 netCDF 操作,尤其是在这种情况下,它会在以后简化您的 Python 编码。

假设文件名为precip_1.ncprecip_2.ncprecip_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,等等。

【讨论】:

  • 终于找到了NCO,完美了。代码效果很好。非常感谢。
  • 太好了,您也可以选择将我的答案作为当时解决您问题的答案。
【解决方案2】:

您可以使用 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'])

【讨论】:

  • 如何将合并后的数据集导出到netcdf文件中?
【解决方案3】:

与 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 

【讨论】:

  • 是否有另一种方法可以在不使用 nco 包的情况下将 netcdf 文件与 python 连接?,我无法使其工作。
  • 我自己没用过,但是python中有一个cdo包接口cdo,见pypi.org/project/cdo——否则你可以使用包“os”中的系统调用来调用cdo跨度>
  • 谢谢@Adrian Tompkins,我也尝试了该选项,但没有成功。我一直在挖掘这个话题,我尝试了几个选项,其中大部分来自 Charlie Zender 本人,我不知道我做错了什么。这就是我想尝试其他东西的原因。
  • 但是如果你在一个 linux 机器上并且安装了 cdo 并且可以工作,那么 os.system 调用必须作为一个后备选项......?
猜你喜欢
  • 1970-01-01
  • 2012-07-26
  • 2021-11-14
  • 1970-01-01
  • 2018-07-06
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 2022-11-19
相关资源
最近更新 更多