熊猫:如何在滚动窗口中选择列

ish*_*243 4 python python-2.7 pandas

我有一个数据框(带有列“ 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)
Run Code Online (Sandbox Code Playgroud)

上一行的目的是在滚动窗口中选择“ a”列的值大于10的第一行。如果没有这样的行,则返回nan。

但我无法这样做,并出现以下错误

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

这意味着此语法完全不允许我访问各个列。还有其他方法可以做这种事情吗?

suv*_*uvy 5

您的错误源于假设apply内部函数涉及的是数据帧,它实际上是ndarray而不是数据帧。

Pandas数据框套用适用于数据框的每个列/系列,因此传递给apply的任何函数都像内部lambda一样沿每个列/系列应用。在使用窗口数据框的情况下,apply会使用每个窗口内的每一列/系列,并以ndarray的形式传递给函数,并且该函数必须仅对每个窗口的每个系列返回长度为1的数组。知道这一点可以节省很多痛苦。

因此,在您的情况下,您不能使用任何apply,除非您具有一个复杂的函数,可以记住a每个窗口的序列的第一个值。

对于OP,如果说窗口的某一列a 满足条件,则说> 10

  1. 如果a窗口的第一行满足条件,则与在dataframe中搜索相同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'))
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

现在,如果a的滚动窗口内的第二行满足a > 10OP的问题中的条件,则选择一个窗口。

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()
Run Code Online (Sandbox Code Playgroud)

上面的行返回窗口第二行中大于10 的a对应于条件的所有值a。请注意,这些值基于上面的示例数据框是正确的,但索引由滚动窗口的居中方式定义。

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
Run Code Online (Sandbox Code Playgroud)

获取正确的索引位置和第一个数据框内的整个行

df.loc[df_y.index+searchindex-rollwindow+1]
Run Code Online (Sandbox Code Playgroud)

退货

    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
Run Code Online (Sandbox Code Playgroud)

还可以使用np.array(df)并制作与滚动窗口相对应的滚动切片,并相应地使用切片对数组进行过滤。