根据每年的每日数据计算月平均值

Posted

技术标签:

【中文标题】根据每年的每日数据计算月平均值【英文标题】:Calculate monthly mean from daily data for each year 【发布时间】:2021-12-18 00:53:04 【问题描述】:

我已经看到很多关于如何根据多年的每日数据计算每月平均值的答案。

但我想要做的是分别从我的 xarray 中每年的每日数据计算每月平均值。因此,我想为每个 lon/lat 网格点得出 2020 年 1 月、2020 年 2 月 ... 2024 年 12 月的平均值。

我的 xarray 的尺寸为 Frozen('time': 1827, 'lon': 180, 'lat': 90) 我尝试使用 var_resampled = var_diff.resample(time='1M').mean() 但这会计算所有年份的平均值(即 2020 年至 2024 年 1 月的平均值)。

我也试过

    def mon_mean(x):
        return x.groupby('time.month').mean('time')

    # group by year, then apply the function:
    var_diff_mon = var_diff.groupby('time.year').apply(mon_mean)

这似乎符合我的要求,但我最终得到了不同的维度(即“月”和“年”而不是原来的“时间”维度)。

有没有一种不同的方法可以分别从每年的每日数据中计算月平均值,或者有没有一种方法可以让上面使用 groupby 的代码现在保留与以前相同的时间维度?

附:我也尝试过“cdo monmean”,但据我了解,这也只是给出了所有年份的月平均值。

谢谢!

解决方案 我找到了一种使用方法

    def mon_mean(x):
        return x.groupby('time.month').mean('time')

    # group by year, then apply the function:
    var_diff_mon = var_diff.groupby('time.year').apply(mon_mean)

然后使用

var_diff_mon.stack(time=("year", "month"))

恢复我原来的时间维度

【问题讨论】:

'我也试过“cdo monmean”,但据我所知,这也只是给出了所有年份的月平均值。这似乎不正确。 monmean 应该做你想做的事。如果不是,您正在使用的 netCDF 文件可能有问题。 @RobertWilson 好的,我会再试一次。从数据结构中,我感觉 monmean 只是计算了所有年份的月平均值。 【参考方案1】:

var_diff.resample(time='M')(或time='MS')是否符合您的预期?

让我们创建一个像你一样的玩具数据集:

import numpy as np
import pandas as pd
import xarray as xr

dims = ('time', 'lat', 'lon')
time = pd.date_range("2021-01-01T00", "2023-12-31T23", freq="H")
lat = [0, 1]
lon = [0, 1]
coords = (time, lat, lon)

ds = xr.DataArray(data=np.random.randn(len(time), len(lat), len(lon)), coords=coords, dims=dims).rename("my_var")
ds = ds.to_dataset()
ds

让我们重新采样:

ds.resample(time="MS").mean()

数据集现在有 36 个时间步长,与原始数据集中的 36 个月相关联。

【讨论】:

您好,问题是它在所有年份中按月重新采样,而我只需要为每年的每个月分别重新采样 你试过这些线吗? ;) 感谢您的帮助。我不知道我在尝试时做错了什么,但这似乎有效:)

以上是关于根据每年的每日数据计算月平均值的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server - 查询以根据每年的最后一个值计算加权平均值

pandas 重新采样以获得具有时间序列数据的月平均值

如何将数据框的单个值除以月平均值?

在 Redshift 中滚动 N 月平均值,每月有多个条目

数据框中每日数据与工作日和周末平均值的偏差

将组平均值分配给 python/pandas 中的每一行