[英]Calculating the mean for each time of day with a rolling window with pandas
我有一個 pandas dataframe ,它有一個日期時間索引和四列Phase 1
、 Phase 2
、 Phase 3
和Sum
。 數據經過預處理,每 15 分鍾有一行,持續數月。 數據非常循環,幾乎每天都在重復,但隨着時間的推移變化緩慢。 目標是在過去一周(或其他時間范圍)的某個時間為所有天生成值的平均值。 (對於機器學習任務)
我已經設法使用此代碼計算了一天中每個時間的平均值:(這會產生一個 1 天長的數據幀)
df.groupby(df.index.hour * 60 + df.index.minute).mean()
Phase 1 Phase 2 Phase 3 Sum
Time
0 10.105782 10.235237 9.990037 30.331055
15 10.106374 10.116440 9.991424 30.214238
30 10.106517 10.086310 10.003420 30.196246
45 10.128441 10.249100 10.032895 30.410436
...
1410 10.112582 10.643766 9.971592 30.727939
1425 10.102739 10.372299 9.969986 30.445025
由於數據逐漸變化,因此所有日子的平均值並不是很好。 如果我可以計算這種類型的平均值會更好,但只包括上周每天的數據。
到目前為止,我嘗試過的是:
df
.groupby(df.index.hour * 60 + df.index.minute)
.rolling("7D", closed="left")
.mean()
它生成正確的數據,但缺少日期信息(需要保留以供將來計算)並且行的順序錯誤。
Phase 1 Phase 2 Phase 3 Sum
Time
0 NaN NaN NaN NaN
0 10.064458 10.051470 10.177814 30.293742
0 10.043804 9.983143 10.062019 30.088965
0 10.020861 9.917236 10.000181 29.938278
...
0 10.224965 10.507418 10.030670 30.763053
0 10.155706 10.396408 9.919538 30.471651
0 10.149112 10.352153 9.894257 30.395522
0 10.144540 10.349998 9.902504 30.397042
15 NaN NaN NaN NaN
15 10.061673 9.967295 10.143008 30.171976
15 10.059581 10.158814 10.051835 30.270230
15 9.995112 10.024808 9.999054 30.018974
...
當第一天沒有完全出現時,還會出現NaN
的問題。 是否需要先刪除不完整的天數,還是可以將它們合並到平均值中?
我也試過這個:
df
.groupby([
pd.Grouper(freq="1D"),
df.index.hour * 60 + df.index.minute
])
.rolling("7D", closed="left")
.mean()
但它產生了一個 dataframe 僅由NaN
組成,所以一定是出了問題。
結果應該是這樣的:
Phase 1 Phase 2 Phase 3 Sum
Time
2021-02-13 00:00:00 11.882597 12.779326 12.458625 37.120549
2021-02-13 00:15:00 11.866148 12.871785 12.509614 37.247547
2021-02-13 00:30:00 11.713676 12.730861 12.525868 36.970405
2021-02-13 00:45:00 11.742079 12.697406 12.592411 37.031897
2021-02-13 01:00:00 11.765234 12.848741 12.622687 37.236662
...
2021-05-01 10:30:00 11.842673 12.190760 12.572203 36.605636
2021-05-01 10:45:00 11.837964 12.118095 12.611271 36.567331
2021-05-01 11:00:00 11.827275 12.220564 12.588131 36.635970
在此示例中,第二行包含2021-02-13 00:15:00
、 2021-02-12 00:15:00
、...、 2021-02-07 00:15:00
的平均值。 我對編程並不陌生,但對 python 和 pandas 相對較新,因此非常感謝任何幫助和提示。
您可以對數據集進行預過濾,使其僅包含dt
日期之前的 13 天,然后按時間分組,使用groupby
min_periods=7
rolling
7 天,取mean
和dropna
以刪除前幾天累積值少於 7 天的日期:
# generate sample dataset
ix = pd.date_range('2021-01-01', '2021-05-01', freq='15min')
df = pd.DataFrame({
'Phase1': np.random.uniform(0, 1, len(ix)),
'Phase2': np.random.uniform(0, 1, len(ix)),
'Phase3': np.random.uniform(0, 1, len(ix)),
}, index=ix)
df['Sum'] = df.sum(1)
# set max date
dt = pd.to_datetime('2021-02-14')
# filter out values in [dt - 13 days, dt)
z = df.loc[(df.index >= dt - pd.DateOffset(days=13)) & (df.index < dt)]
# calculate 7-day rolling average for the same time of the day
# for 7 days preceding `dt`
(z
.groupby(z.index.time)
.rolling('7d', min_periods=7)
.mean()
.dropna()
.droplevel(0)
.sort_index())
Output:
Phase1 Phase2 Phase3 Sum
2021-02-07 00:00:00 0.479466 0.731746 0.503017 1.714229
2021-02-07 00:15:00 0.443550 0.423135 0.543204 1.409889
2021-02-07 00:30:00 0.465272 0.626117 0.454462 1.545851
2021-02-07 00:45:00 0.528733 0.433475 0.386822 1.349029
2021-02-07 01:00:00 0.425309 0.360065 0.488509 1.273884
... ... ... ... ...
2021-02-13 22:45:00 0.519717 0.490549 0.524330 1.534596
2021-02-13 23:00:00 0.367935 0.460093 0.373338 1.201366
2021-02-13 23:15:00 0.597424 0.438130 0.478259 1.513813
2021-02-13 23:30:00 0.675142 0.443580 0.330791 1.449514
2021-02-13 23:45:00 0.474604 0.355723 0.596467 1.426794
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.