【问题标题】:Calculate mean of several months over a longer time period计算较长时间段内几个月的平均值
【发布时间】: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


【解决方案1】:

如果你在 Linux/OSX 上工作,你可以使用我的包 nctoolkit (https://nctoolkit.readthedocs.io/en/latest/index.html) 来完成。

您说您的数据是按月计算的。因此,您要做的是计算窗口为 6 的滚动平均值。虽然滚动平均值通常是使用前后时间计算的。所以在下面的代码中,我使用了滚动和然后除以 6。这将计算 6 个月的平均值,选择 5 月,然后根据需要转换为 xarray。

import nctoolkit as nc
ds = nc.open_data("...\\data.nc")
ds.rolling_sum(window = 6)
ds.divde(6)
ds.select(month=5)
ds_xr = ds.to_xarray()

【讨论】:

  • 很遗憾,我使用的是 Windows,但感谢您的努力。
猜你喜欢
  • 2019-05-19
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 2020-05-20
  • 1970-01-01
  • 1970-01-01
  • 2021-07-11
相关资源
最近更新 更多