如何使用Python将每个月的常数乘以原始时间序列

时间:2019-01-21 19:25:34

标签: python pandas numpy time-series

我正在使用python查看每月的气候数据。基本上,我已经计算了每个月的观测值和模拟值的平均值。我正在“标准化”或将整个模拟时间序列乘以从1964-2013年观察/模拟的比率(每个月1个值)。如何在整个时间序列中将每个月的常数乘以相应的月?

观察到的数据集

Date           Obs   
1964-01-01  2.362798
1964-02-01  2.581734
1964-03-01  1.978354
1964-04-01  1.297320
1964-05-01  2.419230
1964-06-01  1.792333
1964-07-01  1.241412
1964-08-01  1.738074
1964-09-01  0.232911
1964-10-01 -1.790989
1964-11-01  1.902479
1964-12-01  2.304906
1965-01-01  2.913466
1965-02-01  2.895884
1965-03-01  2.457741
1965-04-01  3.435275
1965-05-01  4.428590
1965-06-01  4.530668
1965-07-01  4.096984
1965-08-01  3.543258
1965-09-01  2.856509
1965-10-01  2.817188
1965-11-01  3.838903
1965-12-01  3.985564
...

模拟数据集

Date            Sim
1964-01-01    4.114642
1964-02-01    4.115002
1964-03-01    4.524121
1964-04-01    4.490407
1964-05-01    4.771731
1964-06-01    5.308645
1964-07-01    4.921411
1964-08-01    4.690133
1964-09-01    4.377383
1964-10-01    4.810576
1964-11-01    4.775757
1964-12-01    4.323243
1965-01-01    4.264359
1965-02-01    4.347614
1965-03-01    4.409341
1965-04-01    4.570921
1965-05-01    5.131675
1965-06-01    4.950372
1965-07-01    4.711410
1965-08-01    4.460363
1965-09-01    4.223364
1965-10-01    4.092056
1965-11-01    4.102400
1965-12-01    3.963300
...

我知道如何使用以下方法找到两个数据集每个月的平均值:

    obs_mean=OBS.groupby(OBS.index.strftime("%m")).mean()
    sim_mean=SIM.groupby(OBS.index.strftime("%m")).mean()

然后我可以得到观察/模拟的比率:

    obsarray = np.squeeze(obs_mean.values)
    simarray= np.squeeze(sim_mean.values)
    N_mean=(obsarray)/(simarray)

N_mean产生以下内容:

[0.74664557 0.75842637 0.72030754 0.68142632 0.68588863 0.56606582
 0.54309691 0.54699926 0.50097214 0.48727185 0.71990437 0.75965146]

如何将每个月的N_mean值应用于原始模拟时间序列中的每个月。因此,对于一月N = 0.74664557,我想将此系数乘以模拟时间序列上的每个一月值。要记住的另一件事是,该系数基于50年基线(1964-2013),我想将此系数应用于更大的模拟时间序列(1950-2100)。在熊猫框架内是否更容易做到?任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

首先使用groupbymean计算比率,然后使用reindexsim的所有行中广播结果并相乘。

u = pd.concat([obs, sim], axis=1)
v = u.groupby(u.index.month).mean().eval('Obs / Sim')

sim.mul(v.reindex(obs.index.month).values, axis=0)

答案 1 :(得分:0)

我建议您先将两个帧合并在一起(看起来您正在使用共享时间索引)

joined_df = obs_df.join(sim_df, how="outer")

然后您可以应用-变换groupby值以在原始DataFrame中创建新列

joined_df[["sim_mean", "obs_mean"]] = joined_df.groupby(joined_df.index.month)[["Sim", "Obs"]].transform("mean")

然后您可以找到列的比例

joined_df["n_mean"] = joined_df["obs_mean"]/joined_df["sim_mean"]