从netcdf文件获取每月的每小时平均值

use*_*827 9 python netcdf xarray

我有一个netCDF文件,其时间维度包含2小时的数据.我希望平均每小时获得每小时的平均时数.我试过这个:

import xarray as xr
ds = xr.open_mfdataset('ecmwf_usa_2015.nc')    
ds.groupby(['time.month', 'time.hour']).mean('time')
Run Code Online (Sandbox Code Playgroud)

但我得到这个错误:

*** TypeError: `group` must be an xarray.DataArray or the name of an xarray variable or dimension
Run Code Online (Sandbox Code Playgroud)

我怎样才能解决这个问题?如果我这样做:

ds.groupby('time.month', 'time.hour').mean('time')
Run Code Online (Sandbox Code Playgroud)

我没有得到错误,但结果的时间维度为12(每个月一个值),而我想要每个月的小时平均值,即每12个月24个值.数据可在此处获取:https://www.dropbox.com/s/yqgg80wn8bjdksy/ecmwf_usa_2015.nc?dl = 0

Pra*_*eek 5

你得到TypeError:group必须是xarray.DataArray或xarray变量或维度的名称,因为ds.groupby()应该采用xarray数据集变量或数组,你传递了一个变量列表.

您有两种选择:

1. xarray垃圾箱 - >按小时划分

按文档分组按文档分组,并将数据集转换为splitsbins然后应用groupby('time.hour')

这是因为在一个月或一个小时或一起应用groupby聚合所有数据.如果您将它们拆分为月份数据,则可以按每月的平均值进行分组.

您可以尝试使用文档中提到的方法:

GroupBy:split-apply-combine

xarray支持使用与pandas相同的API进行"分组依据"操作,以实现split-apply-combine策略:

  • 将数据拆分为多个独立的组.=> 按月拆分它们groupby_bins
  • 将一些功能应用于每个组.=> 申请分组
  • 将您的组合并回一个数据对象.**应用聚合函数mean('time')

2.将其转换为pandas数据帧并使用group by

警告:并非所有netcdfs都可以转换为panda数据帧,转换时可能会丢失元数据.

转换成DS大熊猫数据帧通过df = ds.to_dataframe()并根据您的需要使用使用组pandas.Grouper

df.set_index('time').groupby([pd.Grouper(freq='1M'), 't2m']).mean()
Run Code Online (Sandbox Code Playgroud)

注意:我看到了几个答案,pandas.TimeGrouper但已弃用,pandas.Grouper现在必须使用.

由于您的数据集太大而且问题没有最小化数据并且正在消耗大量资源,我建议您在熊猫上查看这些示例

  1. 按工作日分组
  2. 按时间分组
  3. GROUPBY-日期范围-取决于-上的每行
  4. 组和计数行按月和年


Jul*_*les 5

如果你还没有解决问题,你可以这样做:

# define a function with the hourly calculation:
def hour_mean(x):
     return x.groupby('time.hour').mean('time')

# group by month, then apply the function:
ds.groupby('time.month').apply(hour_mean)
Run Code Online (Sandbox Code Playgroud)

这与@Prateek 基于文档给出的第一个选项中的策略相同,但文档对我来说不是那么清楚,所以我希望这有助于澄清。您不能将 groupby 操作应用于 groupby 对象,因此您必须将其构建到一个函数中并使用 .apply() 使其工作。


Adr*_*ins 0

不是 python 解决方案,但我认为这就是在 bash 脚本循环中使用 CDO 的方法:

# loop over months:
for i in {1..12}; do
   # This gives the hourly mean for each month separately 
   cdo yhourmean -selmon,${i} datafile.nc mon${i}.nc
done
# merge the files
cdo mergetime mon*.nc hourlyfile.nc
rm -f mon*.nc # clean up the files
Run Code Online (Sandbox Code Playgroud)

请注意,如果您的数据不是在一月份开始的,那么您将在最终文件时间中得到“跳跃”...我认为可以通过在 yhourmean 命令之后设置年份来排序(如果这对您来说是一个问题)。