2017-06-21 73 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