Python 从netcdf文件中获取每个月的小时平均值
我有一个时间维度的netCDF文件,其中包含2年内按小时计算的数据。我想对它进行平均,得到每个月每天每小时的平均小时数。我试过这个:Python 从netcdf文件中获取每个月的小时平均值,python,netcdf,xarray,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') 但我得到了这个错误: *** TypeError: `group` must be an xarray.DataArray
import xarray as xr
ds = xr.open_mfdataset('ecmwf_usa_2015.nc')
ds.groupby(['time.month', 'time.hour']).mean('time')
但我得到了这个错误:
*** TypeError: `group` must be an xarray.DataArray or the name of an xarray variable or dimension
我怎样才能解决这个问题?如果我这样做:
ds.groupby('time.month', 'time.hour').mean('time')
我没有得到错误,但结果的时间维度为12(每个月一个值),而我想要每个月的小时平均值,即12个月中的每个月24个值。这里有数据:不是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
请注意,如果您的数据没有在1月份开始,那么您将在最终文件时间内得到一个“跳跃”。。。我认为,如果这是您的问题,可以通过设置yhourmean命令后的年份来排序。这是什么
import xarray as xr
ds = xr.open_mfdataset('ecmwf_usa_2015.nc')
print ds.groupby('time.hour' ).mean('time')
我有这样的感觉:
尺寸:(小时:24,纬度:93,经度:
281)坐标:
- 经度(经度)32 230.0 230.25 230.5 230.75 231.0 231.25 ... * 纬度(纬度)浮动32 48.0 47.75 47.5 47.25 47.0 46.75 46.5…*小时(小时)国际64 01 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
我想这就是你想要的。你得到了类型错误:
组
必须是xarray.DataArray或xarray变量或维度的名称,因为ds.groupby()应该接受xarray数据集变量或数组,所以你传递了一个变量列表
您有两个选择:
1.X阵列箱-->按小时分组
参考分组文档,将数据集转换为拆分
或存储箱
,然后应用groupby('time.hour')
这是因为将groupby应用于每月,然后逐个应用小时,或者一起应用小时,是对所有数据的聚合。如果你将它们分割成月份数据,你将在每个月应用分组平均值
您可以尝试文档中提到的这种方法:
GroupBy:split-apply-combine
xarray支持“分组方式”操作,其API与pandas to相同
实施拆分应用联合收割机策略:
- 将数据拆分为多个独立组。=>使用
groupby\u bins将它们按月份分割
- 对每个组应用一些函数。=>应用分组依据
- 将您的组重新组合到单个数据对象中**应用聚合函数
mean('time')
df=ds.to_dataframe()
将ds转换为熊猫数据帧并使用
使用pandas.gropper
like按需要分组
df.set_index('time').groupby([pd.Grouper(freq='1M'), 't2m']).mean()
注意:我看到了关于pandas.TimeGrouper
的两个答案,但它已被弃用,现在必须使用pandas.Grouper
由于您的数据集太大,而且问题并没有最小化数据,并且在处理数据时会消耗大量资源,所以我建议您看看这些关于熊猫的示例
如果你还没有解决问题,你可以这样做:
# 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)
这与@Prateek给出的第一个选项中的策略相同,并且基于文档,但是文档对我来说不是很清楚,所以我希望这有助于澄清。无法将groupby操作应用于groupby对象,因此必须将其构建到函数中并使用.apply()使其正常工作。使用xarray库通过netcdf文件检索多时groupby函数的另一个解决方案是使用称为“重采样”的xarray DataArray方法以及“groupby”方法。这种方法也适用于xarray数据集对象 通过这种方法,可以检索值,如每月每小时平均值或其他类型的时间聚合(即:年-月平均值、两年-三个月总和等) 下面的示例使用每日气温(Tair)的标准xarray教程数据集。请注意,我必须将教程数据的时间维度转换为datetime对象。如果未应用此转换,则重采样功能将失败,并显示错误消息(见下文): 错误消息: TypeError:仅对DatetimeIndex、TimedeltaIndex或PeriodIndex有效,但得到了'Index'的实例 尽管存在时间索引问题(这可能是StackOverFlow中讨论的另一个问题),下面的代码为xarray对象中的多时分组问题提供了两种可能的解决方案。第一个使用xarray.core.groupby.DataArrayGroupBy类,而第二个仅使用普通xarray dataArray和xarray DataSet类中的groupby方法 诚挚的 菲利佩·里斯卡拉·莱尔 代码段:
ds = xr.tutorial.open_dataset('rasm').load()
def parse_datetime(time):
return pd.to_datetime([str(x) for x in time])
ds.coords['time'] = parse_datetime(ds.coords['time'].values)
# 1° Option for multitemporal aggregation:
time_grouper = pd.Grouper(freq='Y')
grouped = xr.core.groupby.DataArrayGroupBy(ds, 'time', grouper=time_grouper)
for idx, sub_da in grouped:
print(sub_da.resample({'time':'3M'}).mean().coords)
# 2° Option for multitemporal aggregation:
grouped = ds.groupby('time.year')
for idx, sub_da in grouped:
print(sub_da.resample({'time':'3M'}).mean().coords)
我相信
ds
是一个而不是一个,对吗?请提供一些样本数据,并澄清在没有数据的情况下,小时会发生什么。如果应考虑缺失数据,则需要重新采样too@SiggyF,您是对的,ds是通过在netCDF中读取而生成的xarray.Datasetfile@MaartenFabr首先,我将尝试获取一个示例数据集(完整数据集的大小为seveal GBs)。您可以假设不存在缺失数据—使用虚拟(如随机)数据的最小示例通常效果最好。虽然重点关注熊猫,但这个问题/答案可能会有所帮助:谢谢@Adrian,我正在寻找python soln,但我很感激你的努力。我也这么认为。但这是24。OP需要24*12