簡體   English   中英

在 Pandas 中的 GroupBy 內檢查負滾動窗口中的條件

[英]Checking condition in negative rolling window within GroupBy in Pandas

以下是我的數據框的樣子。 Expected_Output列是我想要的/目標列。

   Group  Value  Expected_Output
0      1      2                1
1      1      3                1
2      1      6                1
3      1     11                0
4      1      7                0
5      2      3                1
6      2     13                1
7      2     14                0

對於給定的Group ,從給定的行開始,我正在查看接下來的5 行並檢查是否有任何Value > 10 如果為真,那么我想在Expected_Output返回 1,否則返回 0。

例如,在Group 1 ,從第一行開始, Value 11(大於 10)出現在 3 行內,並且確實落在滿足條件的“下 5 行窗口”內,因此返回 1在Expected_Output Group 2的第 6 行類似, Value 14(大於 10)出現在 1 行內,並且確實落在滿足條件的“下 5 行窗口”內,因此在Expected_Output返回 1。

我試過df.groupby('Group')['Value'].rolling(-5).max() > 10無濟於事。

默認情況下, pd.Series.rolling向后看。 若要向前看,可以反轉數據框,然后反轉GroupBy結果。 您需要包括一個shift因為您正在尋找下一個 5個值。

def roller(x):
    return x.rolling(window=5, min_periods=1)['Value'].max().shift().gt(10).astype(int)

df['Result'] = df.iloc[::-1].groupby('Group', sort=False).apply(roller).iloc[::-1].values

print(df)

   Group  Value  Result
0      1      2       1
1      1      3       1
2      1      6       1
3      1     11       0
4      1      7       0
5      2      3       1
6      2     13       1
7      2     14       0

您可以嘗試對數據幀進行分組,並利用數據幀索引來獲取下一個可能的5個值,並檢查是否有大於10的任何值

df['Expected_Output'] =df.groupby(['Group'])['Value'].transform(lambda y:list(map(lambda x: 1 if any(y.loc[set(np.arange(x+1,x+6)).intersection(y.index)] >10) else 0,y.index)))

出:

    Group   Value   Expected_Output
0   1   2   1
1   1   3   1
2   1   6   1
3   1   11  0
4   1   7   0
5   2   3   1
6   2   13  1
7   2   14  0

有一種方法可以在沒有任何額外技巧的情況下做到這一點,但它需要您有一個排序維度。 與大多數時間序列數據一樣,您應該擁有可用的時間變量。 那么解決方法很簡單:

  1. 向后排序
  2. 使用標准的.rolling(window)功能
  3. (可選)再次排序

示例:睡眠研究

from pydataset import data
sleep_study = data('sleepstudy')
print(sleep_study.head(5))
   Reaction  Days  Subject
1  249.5600     0      308
2  258.7047     1      308
3  250.8006     2      308
4  321.4398     3      308
5  356.8519     4      308

1)向后排序

sleep_study.sort_values(by=['Subject', 'Days'], ascending=False, inplace=True)

2) 使用.rolling(window)

sleep_study['max_react_next_3_days'] = sleep_study\
    .groupby('Subject')['Reaction']\
    .rolling(window=3, min_periods=1, closed='left').max()\
    .droplevel(level=0)
sleep_study['expected_output'] = sleep_study['max_react_next_3_days'] > 400

解釋:

  • 我們要向前看 3 天,因此window=3
  • 但是,研究中只剩下 2 或 1 天也可以,所以min_periods=1 -- 這取決於您的假設/喜好
  • 我們想使用接下來的3 天,而不是當天,所以我們使用closed='left'排除它,這意味着rolling需要一個半開區間,在“右邊”打開,在“左邊”關閉”。

3)再次排序,以免有意外

sleep_study.sort_values(by=['Subject', 'Days'], ascending=True, inplace=True)

結果:

print(sleep_study.head(20))
    Reaction  Days  Subject  max_react_next_3_days  expected_output
1   249.5600     0      308               321.4398            False
2   258.7047     1      308               356.8519            False
3   250.8006     2      308               414.6901             True
4   321.4398     3      308               414.6901             True
5   356.8519     4      308               414.6901             True
6   414.6901     5      308               430.5853             True
7   382.2038     6      308               466.3535             True
8   290.1486     7      308               466.3535             True
9   430.5853     8      308               466.3535             True
10  466.3535     9      308                    NaN            False
11  222.7339     0      309               205.2658            False
12  205.2658     1      309               207.7161            False
13  202.9778     2      309               215.9618            False
14  204.7070     3      309               215.9618            False
15  207.7161     4      309               217.7272            False
16  215.9618     5      309               224.2957            False
17  213.6303     6      309               237.3142            False
18  217.7272     7      309               237.3142            False
19  224.2957     8      309               237.3142            False
20  237.3142     9      309                    NaN            False

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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