簡體   English   中英

熊貓:如何在滾動窗口中選擇一列

[英]Pandas: How to select a column in rolling window

我有一個數據框(列'a','b','c'),我正在做一個滾動窗口。

我希望能夠使用apply函數中的一個列(比如'a')過濾滾動窗口,如下所示

df.rolling(len(s),min_periods=0).apply(lambda x: x[[x['a']>10][0] if len(x[[x['a']>10]]) >=0 else np.nan)

上面一行的意圖是選擇滾動窗口中第一行的'a'列的值大於10.如果沒有這樣的行,則返回nan。

但我無法這樣做並得到以下錯誤

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

這意味着我不允許通過這種語法訪問各個列。 有沒有其他辦法做這種事情?

你的錯誤源於假設里面的函數應用是一個數據幀,它實際上是一個ndarray而不是一個數據幀。

大熊貓數據幀上每列/系列數據幀的應用作品,所以沿每一列/系列等的內部拉姆達施加傳遞給應用任何功能。 在窗口化數據幀的情況下,apply將每個窗口中的每個列/系列作為ndarray傳遞給函數,並且該函數必須每個窗口每個系列只返回長度為1的數組。 知道這可以節省很多痛苦。

所以在你的情況下你不能使用任何apply,除非你有一個復雜的函數來記住每個窗口的系列a第一個值。

對於OP的情況,如果窗口的一列表示a滿足條件,則說> 10

  1. 對於其中殼體a窗口的第一行中滿足調節它是相同數據幀搜索df[df['a']>10]

  2. 對於像其他條件a在窗口中的第二行是> 10 ,檢查整個數據幀作品除數據幀的第一個窗口。

以下示例演示了另一種解決方法。

import numpy as np
import pandas as pd
np.random.seed(123)
df = pd.DataFrame(np.random.randint(0,20,size=(20, 4)), columns=list('abcd'))

df看起來像

    a   b   b   d
0   13  2   2   6
1   17  19  10  1
2   0   17  15  9
3   0   14  0   15
4   19  14  4   0
5   16  4   17  3
6   2   7   2   15
7   16  7   9   3
8   6   1   2   1
9   12  8   3   10
10  5   0   11  2
11  10  13  18  4
12  15  11  12  6
13  13  19  16  6
14  14  7   11  7
15  1   11  5   18
16  17  12  18  17
17  1   19  12  9
18  16  17  3   3
19  11  7   9   2

現在要選擇一個窗口,如果在滾動窗口內的第二行滿足條件a > 10就像在OP的問題中那樣。

roll_window=5
search_index=1

df_roll = df['a'].rolling(roll_window)
df_y = df_roll.apply(lambda x:x[1] if x[1] > 10 else np.nan).dropna()

上面的行返回的所有值a對應於條件a在窗口中的第二行大於10。注意值是正確的基於例如數據幀以上但指數是通過在窗口如何軋制居中限定。

4     17.0
7     19.0
8     16.0
10    16.0
12    12.0
15    15.0
16    13.0
17    14.0
19    17.0

獲取正確的索引位置和第一個數據幀內的整行

df.loc[df_y.index+searchindex-rollwindow+1]

回報

    a   b   b   d
1   17  19  10  1
4   19  14  4   0
5   16  4   17  3
7   16  7   9   3
9   12  8   3   10
12  15  11  12  6
13  13  19  16  6
14  14  7   11  7
16  17  12  18  17

也可以使用np.array(df)並制作對應於滾動窗口的滾動切片,並相應地使用切片過濾數組。

首先,制作滾動窗口:

win = df['a'].rolling(len(s), min_periods=0)

然后創建你的條件(布爾數組):

cond = win > 10

最后:

idx = np.where(cond)[0]
return win.iloc[idx[0]] if len(idx) else np.nan

暫無
暫無

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

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