【发布时间】:2021-03-20 21:10:14
【问题描述】:
我有几十年的 netCDF 月度温度数据,并想计算一年中每个月的所有年份的 6 个月平均值。例如,要获得 5 月的 6 个月平均值,我必须将每年的 5 月和所有 5 个月(12 月、1 月、2 月、3 月、4 月)相加,然后计算平均值。我尝试申请this guide,但使用的是六个月平均值而不是季节性平均值。
import pandas as pd
import xarray as xr
import numpy as np
ds = xr.open_dataset("...\\data.nc")
# Make a DataArray with the number of days in each month, size = len(time)
month_length = ds.time.dt.days_in_month
# Calculate the weights by grouping by 6 months
weights = xr.core.groupby.DataArrayGroupBy(month_length, 'time', grouper=pd.Grouper(freq='6MS')) / xr.core.groupby.DataArrayGroupBy(month_length, 'time', grouper=pd.Grouper(freq='6MS')).sum()
print(weights)
# Test that the sum of the weights for each season is 1.0
np.testing.assert_allclose(xr.core.groupby.DataArrayGroupBy(weights, 'time', grouper=pd.Grouper(freq='6MS')).sum().values, np.ones(2))
# Calculate the weighted average
ds_weighted = xr.core.groupby.DataArrayGroupBy((ds * weights), 'time', grouper=pd.Grouper(freq='6MS')).sum(dim='time')
ds.to_netcdf(path="..\\output.nc")
但由于某种原因,权重似乎加起来不等于 1。
编辑:我现在决定尝试另一种方法来解决体重问题。首先,我决定将数据乘以当月的天数:
month_length = ds.time.dt.days_in_month
ds_multbymonth = ds * month_length
然后我计算 6 个月的滚动总和。
ds_rolledSum = ds_multbymonth.rolling(time=6, min_periods=6).sum().stack().reset_index('time')
最后我想按月对汇总的变量进行分组,以便稍后将它们除以每个 6 个月总和的天数:
sumSixMonths = ds_rolledSum.groupby('time.month').sum()
这是一个相当不雅的解决方案,也许这里有人有更好的建议。
【问题讨论】:
-
一切正常。您不知道
import calendar/calendar.monthrange(2020,6)返回该月的起始工作日和天数吗? -
所有的日历工作都是从网站上复制过来的。对我来说,重要的问题是让调整后的重量计算正常工作。
-
@sarah356 我实际上认为你的更新方法,
rolling,然后是groupby,几乎是尽可能干净。只是好奇stack().reset_index("time")的原因是什么?我的直觉说你应该可以不用它,但我不知道你的数据集/问题的全部细节。 -
@spencerkclark 你是绝对正确的。我一开始以为我必须重新索引这些项目,但它们仍然井然有序,所以我可以删除它。
标签: python netcdf python-xarray