バイテンポラル データセットで移動平均を計算しようとしています。データセットは、データの日付と有効日 (データが利用可能になった日付) で構成されます。この日付のデータは、今後数回修正される可能性があります (データの日付は同じですが、発効日は異なります)。計算対象の行の発効日に有効なデータを使用して、過去 4 四半期の移動平均を計算する必要があります。
データセットは次のようになります
ID | データ日付 | 無効にする | 価値 |
---|---|---|---|
1 | 2005-03-31 | 2005-04-15 | 10 |
1 | 2005-03-31 | 2005-05-30 | 11 |
1 | 2005-06-30 | 2005-07-15 | 9 |
1 | 2005-06-30 | 2005-08-20 | 9.5 |
1 | 2005-06-30 | 2005-10-15 | 9.6 |
1 | 2005-09-30 | 2005-10-15 | 10.5 |
1 | 2005-09-30 | 2005-11-10 | 11 |
1 | 2005-09-30 | 2006-02-20 | 10.75 |
1 | 2005-12-31 | 2006-02-13 | 12 |
1 | 2005-12-31 | 2006-02-20 | 11.6 |
1 | 2005-12-31 | 2006-05-10 | 11 |
1 | 2006-03-31 | 2006-04-20 | 8 |
1 | 2006-03-31 | 2006-05-10 | 8.25 |
結果は
ID | データ日付 | 無効にする | 価値 | MAvg | |
---|---|---|---|---|---|
0 | 1 | 2005-03-31 | 2005-04-15 | 10 | 10 |
1 | 1 | 2005-03-31 | 2005-05-30 | 11 | 11 |
2 | 1 | 2005-06-30 | 2005-07-15 | 9 | 10 |
3 | 1 | 2005-06-30 | 2005-08-20 | 9.5 | 10.25 |
4 | 1 | 2005-06-30 | 2005-10-15 | 9.6 | 10.30 |
5 | 1 | 2005-09-30 | 2005-10-15 | 10.5 | 10.37 |
6 | 1 | 2005-09-30 | 2005-11-10 | 11 | 10.53 |
7 | 1 | 2005-09-30 | 2006-02-20 | 10.75 | 10.45 |
8 | 1 | 2005-12-31 | 2006-02-13 | 12 | 10.9 |
9 | 1 | 2005-12-31 | 2006-02-20 | 11.5 | 10.71 |
10 | 1 | 2005-12-31 | 2006-05-10 | 11 | 10.59 |
11 | 1 | 2006-03-31 | 2006-04-20 | 8 | 9.96 |
12 | 1 | 2006-03-31 | 2006-05-10 | 8.25 | 9.9 |
私はパンダを使ってPythonでこれをやっています。私がこれを行っている方法は、データフレームを id と前の 4 四半期で結合し、過去 4 四半期の effdates に基づいてすべての期間の新しい effdates を計算することです。次に、id、datadate、および effdate でもう一度結合して計算します平均。
keys["id"]
calc_df = df1.merge(df2, on=keys, how='left')
calc_df = calc_df.loc[
(calc_df["datadate_x"] >= calc_df["datadate_y"])
& (calc_df["datadate_y"] >= calc_df["datadate_x"] - pd.tseries.offsets.MonthEnd(n=9))
& (calc_df["effdate_x"] <= calc_df["thrudate_y"])
& (calc_df["thrudate_x"] >= calc_df["effdate_y"])
]
calc_df = calc_df.drop_duplicates().reset_index(drop=True)
grp_keys = keys + ["datadate_x"]
calc_df["effdate"] = calc_df[["effdate_x", "effdate_y"]].max(axis=1)
calc_df = calc_df.sort_values(grp_keys + ["effdate"]).drop_duplicates(
subset=grp_keys + ["effdate"], keep="first"
)
calc_df = calc_df['id', 'datadate_x', 'effdate', 'value']
calc_df = calc_df.merge(df1, on=["id"], how="left")
calc_df = calc_df.loc[
(calc_df["datadate_x"] >= calc_df["datadate"])
& (
calc_df["datadate"]
>= calc_df["datadate_x"] - pd.tseries.offsets.MonthEnd(n=9)
)
& (calc_df["effdate_x"] <= calc_df["thrudate_y"])
& (calc_df["thrudate_x"] >= calc_df["effdate_y"])
]
calc_df["MAvg"] = calc_df.groupby(["id", "datadate_x", "effdate_x"])["value"].transform(
lambda s: s.mean(skipna=False)
)
これは機能しますが、2000年から最新の四半期(約50万行)までの約2000の異なるIDとデータ日付を持つ完全なデータセットで実行すると非常に遅くなり、異なるウィンドウのいくつかのフィールドで移動平均を計算する必要があります。そこで、効率の良い方法があれば教えていただきたいです。