【问题标题】:Extract groups of consecutive values having greater than specified size提取大于指定大小的连续值组
【发布时间】:2019-01-02 17:07:13
【问题描述】:

我试图在数据框中查找是否至少有 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

如何子集我需要的操作?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案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
    

    【讨论】:

    • 这实际上是“分组依据”操作的一部分(按 CRD 列)。如果有两组连续的行(Crd 111 和 333),并且第二组行不满足条件(不是连续 4 个 True),则包含该组的第一行(粗线),当它应该't
    【解决方案2】:

    这也将考虑连续 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
    

    【讨论】:

      【解决方案3】:

      一种可能的选择是使用itertools.groupby 在源上调用 df.values.

      pd.groupby相比,此方法的一个重要区别是 如果分组键发生变化,则会创建一个新组。

      所以你可以试试下面的代码:

      import pandas as pd
      import itertools
      
      # Source DataFrame
      df = pd.DataFrame(data=[
          [ 5153, '04/04/2017 11:40:00', True ], [ 7542, '04/04/2017 17:18:00', True ],
          [  875, '04/04/2017 20:08:00', True ], [   74, '05/04/2017 20:30:00', False ],
          [ 9652, '06/04/2017 20:32:00', True ], [  965, '07/04/2017 12:52:00', True ],
          [  752, '10/04/2017 17:40:00', True ], [ 9541, '10/04/2017 19:29:00', True ],
          [ 7452, '11/04/2017 12:20:00', True ], [ 9651, '12/04/2017 13:57:00', False ]],
          columns=[ 'TRN', 'TRN_DATE', 'FILTER_OK' ])
      # Work list 
      xx = []
      # Collect groups for 'True' key with at least 5 members
      for key, group in itertools.groupby(df.values, lambda x: x[2]):
          lst = list(group)
          if key and len(lst) >= 5:
              xx.extend(lst)
      # Create result DataFrame with the same column names
      df2 = pd.DataFrame(data=xx, columns=df.columns)
      

      【讨论】:

        【解决方案4】:

        这实际上是“分组依据”操作的一部分(按 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
        

        【讨论】:

          猜你喜欢
          • 2022-01-07
          • 1970-01-01
          • 2016-04-01
          • 2019-02-09
          • 1970-01-01
          • 2022-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多