2017-06-21 87 views
1

我有一個數據框(帶有'a','b','c'列),我正在做一個滾動窗口。熊貓:如何在滾動窗口中選擇一列

我希望能夠過濾使用其中一列的滾動窗口中像下面

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」) 'a'列的值大於10的滾動窗口。如果沒有這樣的行,則返回nan。

不過,我不能這樣做,收到以下錯誤

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

這意味着我不能用這種語法在所有訪問各列。 有沒有其他方式做這種事情?

+0

您是否檢查過x [[x ['a']> 10] [0]'是什麼? –

+0

@AndrewL顯然我不允許訪問'a'列。錯誤是指索引只能是整數,切片(':'),省略號('...'),numpy.newaxis('無')和整數或布爾數組。 – ishan3243

+1

這將是非常有用的查看示例數據 –

回答

2

你錯誤的假設莖會發生什麼對於裏面應用的函數是一個數據幀,它實際上是一個ndarray而不是一個數據幀。

熊貓數據幀應用在每列/系列數據幀的作品,因此傳遞給應用任何函數沿施加每列/系列等的內部的λ。在窗口數據幀的情況下,apply將每個窗口內的每個列/序列作爲ndarray傳遞給函數,函數必須僅返回每個窗口每個序列長度爲1的數組。瞭解這一點可以節省很多痛苦。

所以在你的情況下,除非你有一個複雜的功能,爲每個窗口記住系列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 

現在選擇一個窗口,如果裏面滾動的窗口,第二排OP的問題,滿足條件的情況a > 10等。

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)並做出相應的滾動窗口滾動片和使用切片相應地過濾數組。

+0

關於第一排滾動窗口,這只是我給的一個例子。 – ishan3243

+0

@ ishan3243其他行也應該給出類似的答案,除了第一個窗口。儘管我確實爲你製作了另一個通用的解決方案 – suvy

0

首先,滾動窗口:

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 
+0

我不確定是否理解代碼中發生了什麼。 cond變量對我來說沒有意義。你能解釋一下嗎? – ishan3243

+0

@John Zwinck你的條件是布爾不是布爾陣列,所以似乎沒有工作 – suvy