簡體   English   中英

使用滾動 window 和 pandas 計算一天中每個時間的平均值

[英]Calculating the mean for each time of day with a rolling window with pandas

我有一個 pandas dataframe ,它有一個日期時間索引和四列Phase 1Phase 2Phase 3Sum 數據經過預處理,每 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:002021-02-12 00:15:00 、...、 2021-02-07 00:15:00的平均值。 我對編程並不陌生,但對 python 和 pandas 相對較新,因此非常感謝任何幫助和提示。

您可以對數據集進行預過濾,使其僅包含dt日期之前的 13 天,然后按時間分組,使用groupby min_periods=7 rolling 7 天,取meandropna以刪除前幾天累積值少於 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM