提取具有大于指定大小的连续值的组

时间:2019-01-02 17:07:14

标签: python pandas dataframe

我试图在一个数据帧中查找是否至少有X个连续的操作(我已经包括了一个“ Filter_OK”列,用于计算该行是否符合条件),并提取该组行。

      TRN     TRN_DATE          FILTER_OK  
0   5153    04/04/2017 11:40:00      True
1   7542    04/04/2017 17:18:00      True
2   875     04/04/2017 20:08:00      True
3   74      05/04/2017 20:30:00     False
4   9652    06/04/2017 20:32:00      True
5   965     07/04/2017 12:52:00      True
6   752     10/04/2017 17:40:00      True
7   9541    10/04/2017 19:29:00      True
8   7452    11/04/2017 12:20:00      True
9   9651    12/04/2017 13:57:00     False

对于此示例,如果我要查找4个操作。
期望的输出:

    TRN     TRN_DATE    FILTER_OK  
4   9652    06/04/2017  20:32:00    True 
5   965     07/04/2017  12:52:00    True
6   752     10/04/2017  17:40:00    True
7   9541    10/04/2017  19:29:00    True
8   7452    11/04/2017  12:20:00    True

我该如何细分我需要的操作?

4 个答案:

答案 0 :(得分:1)

您可以使用cumsum,然后使用groupbytransform进行此操作:

v = (~df.FILTER_OK).cumsum()
df[v.groupby(v).transform('size').ge(4) & df['FILTER_OK']]

    TRN            TRN_DATE  FILTER_OK
4  9652 2017-06-04 20:32:00       True
5   965 2017-07-04 12:52:00       True
6   752 2017-10-04 17:40:00       True
7  9541 2017-10-04 19:29:00       True
8  7452 2017-11-04 12:20:00       True

详细信息
首先,使用cumsum将行分成几组:

v = (~df.FILTER_OK).cumsum()
v

0    0
1    0
2    0
3    1
4    1
5    1
6    1
7    1
8    1
9    2
Name: FILTER_OK, dtype: int64

下一步,找到每个组的大小,然后找出哪些组至少具有X行(在您的情况下为4行):

v.groupby(v).transform('size')

0    3
1    3
2    3
3    6
4    6
5    6
6    6
7    6
8    6
9    1
Name: FILTER_OK, dtype: int64

v.groupby(v).transform('size').ge(4)

0    False
1    False
2    False
3     True
4     True
5     True
6     True
7     True
8     True
9    False
Name: FILTER_OK, dtype: bool

并使用“ FILTER_OK”将此掩码并确保我们仅采用符合条件的有效行。

v.groupby(v).transform('size').ge(4) & df['FILTER_OK']

0    False
1    False
2    False
3    False
4     True
5     True
6     True
7     True
8     True
9    False
Name: FILTER_OK, dtype: bool

答案 1 :(得分:1)

这还将考虑连续4个False

s=df.FILTER_OK.astype(int).diff().ne(0).cumsum()
df[s.isin(s.value_counts().loc[lambda x : x>4].index)]
Out[784]: 
    TRN            TRN_DATE  FILTER_OK
4  9652  06/04/201720:32:00       True
5   965  07/04/201712:52:00       True
6   752  10/04/201717:40:00       True
7  9541  10/04/201719:29:00       True
8  7452  11/04/201712:20:00       True

答案 2 :(得分:0)

一种可能的选择是使用在源代码上调用的https://github.com/<our-org>/<repo>/commits/master itertools.groupby

df.values相比,此方法的重要区别是 如果分组键发生更改,则会创建一个新组。

因此您可以尝试以下代码:

pd.groupby

答案 3 :(得分:0)

这实际上是“分组依据”操作(按CRD列)的一部分。 如果有两个连续的行组(Crd 111和333),而第二个行组不满足条件(不是连续的4个True),则应包括该组的第一行(粗线) 't

CRD     TRN     TRN_DATE            FILTER_OK

0    111    5153    04/04/2017 11:40:00     True

1       111     7542    04/04/2017 17:18:00     True

2       256     875     04/04/2017 20:08:00     True

3       365     74      05/04/2017 20:30:00     False

4       111     9652    06/04/2017 20:32:00     True

5       111     965     07/04/2017 12:52:00     True

6       111     752     10/04/2017 17:40:00     True

7       111     9541    10/04/2017 19:29:00     True

**8     333     7452    11/04/2017 12:20:00     True**

9       333     9651    12/04/2017 13:57:00     False

10      333     961     12/04/2017 13:57:00     False

11      333     871     12/04/2017 13:57:00     False

Actual output:

    CRD  TRN     TRN_DATE          FILTER_OK  
4   111  9652    06/04/2017 20:32:00      True

5   111  965     07/04/2017 12:52:00      True

6   111  752     10/04/2017 17:40:00      True

7   111  9541    10/04/2017 19:29:00      True

**8   333  7452    11/04/2017 12:20:00      True**

Desired output:

    CRD  TRN     TRN_DATE          FILTER_OK  
4   111  9652    06/04/2017 20:32:00      True

5   111  965     07/04/2017 12:52:00      True

6   111  752     10/04/2017 17:40:00      True

7   111  9541    10/04/2017 19:29:00      True