来自这里的玩具数据集
import numpy as np
import pandas as pd
import seaborn as sns
import xarray as xr
np.random.seed(123)
xr.set_options(display_style="html")
times = pd.date_range("2000-01-01", "2001-12-31", name="time")
annual_cycle = np.sin(2 * np.pi * (times.dayofyear.values / 365.25 - 0.28))
base = 10 + 15 * annual_cycle.reshape(-1, 1)
tmin_values = base + 3 * np.random.randn(annual_cycle.size, 3)
tmax_values = base + 10 + 3 * np.random.randn(annual_cycle.size, 3)
ds = xr.Dataset(
{
"tmin": (("time", "location"), tmin_values),
"tmax": (("time", "location"), tmax_values),
},
{"time": times, "location": ["IA", "IN", "IL"]},
)我知道这里,我可以找到如何从xarray.DataSet()中的变量中减去每月平均值,如下所示:
climatology = ds.groupby("time.month").mean("time")
anomalies = ds.groupby("time.month") - climatology
anomalies.mean("location").to_dataframe()[["tmin", "tmax"]].plot()那么,我能为每个位置做减法吗?
我试着为位置月组做这件事,但是xarray.DataSet.groupby()不允许传递多个组。然后,我尝试使用xarray.DataSet.stack()创建location,但它只允许传递维度;我可以使用time.month提取月份值,但它们被还原为一个新变量,而不是维度。我可以对所有位置使用for或xarray.DataSet.apply(),但速度太慢(我有大约65000个位置)。
预期的结果或过程类似于:
for each location:
climatology = ds.groupby("time.month").mean("time")
anomalies = ds.groupby("time.month") - climatology只有xarray内部的解决方案是最好的,但是如果使用pd.DataFrame()或其他解决方案是可能的,而且速度相当快,那么这些解决方案也是受欢迎的。
编辑
下面是我使用`pd.DataFrame()的当前解决方案
# convert to pd.dataframe
df = ds.to_dataframe()
# get mean monthly values
months = df.index.get_level_values('time').month
df_meanMonths = df.groupby([pd.Grouper(level='location'), months]).mean()
# rename and reindex
df_meanMonths.rename(columns={'tmin': 'tminMM', 'tmax': 'tmaxMM'}, inplace=True)
df_meanMonths.index.set_names('month', level='time', inplace=True)
# merge
df['month'] = df.index.get_level_values('time').month
vars_join = ['tminMM', 'tmaxMM']
join_right = df_meanMonths[vars_join]
# results
df.reset_index().set_index(['location', 'month']).merge(join_right, how='left', left_index=True, right_on=['location', 'month'])发布于 2022-11-18 12:48:32
我想你可能想找的是:
anomalies = xr.apply_ufunc(
lambda x, mean: x - mean,
ds.tmax.groupby('time.month'),
ds.tmax.groupby('time.month').mean()
).drop('month')仅用于tmax变量( DataArray)或
anomalies = xr.apply_ufunc(
lambda x, means: x - means,
ds.groupby('time.month'),
ds.groupby('time.month').mean()
).drop('month')用于数据集中的所有变量。
https://stackoverflow.com/questions/66903278
复制相似问题