【问题标题】:How to count consective 1 in column and get max count of each group如何计算列中的连续 1 并获取每组的最大计数
【发布时间】:2020-07-10 16:35:42
【问题描述】:

我有包含“A”和“标志”列的数据框。我想应用 groupby 函数并获得每组中连续 1 的最大计数

输入数据:

df=pd.DataFrame({'A':[1,1,1,1,1,1,2,2,2,2,2,2,2],'flag':[1,1,0,1,1,1,0,1,1,0,1,1,1]}) 

需要的输出

output= pd.DataFrame({'A':[1,1,1,1,1,1,2,2,2,2,2,2,2],'consective_count_max':[3,3,3,3,3,3,3,3,3,3,3,3,3]})  

【问题讨论】:

    标签: python-3.x pandas numpy pandas-groupby


    【解决方案1】:

    IIUC、GroupBy.sumSeries.maxlevel=0。 我们可以使用Series.map 来创建一个带有原始索引的系列:

    blocks=df['flag'].ne(df['flag'].shift()).cumsum()
    df['consecutive_count_max'] = (df['A'].map(df.groupby(['A',blocks])['flag']
                                                 .sum()
                                                 .max(level=0)))
    print(df)
    
        A  flag  consecutive_count_max
    0   1     1                      3
    1   1     1                      3
    2   1     0                      3
    3   1     1                      3
    4   1     1                      3
    5   1     1                      3
    6   2     0                      3
    7   2     1                      3
    8   2     1                      3
    9   2     0                      3
    10  2     1                      3
    11  2     1                      3
    12  2     1                      3
    

    请注意,添加时,flag == 0 组的总和永远不会大于flag == 1 组,因此df['flag'].eq(1) 不是必需的

    如果flag不是1或0,则需要检查例如df['flag'].eq('yes')。我们可以使用:

    mapper = pd.crosstab(df['flag'].ne(df['flag'].shift())
                                   .cumsum()
                                  .loc[df['flag'].eq(1)], df['A']).max()
    df['consecituve_count_max'] = df['A'].map(mapper)
    #print(df)
    

    详情

    print(df['flag'].ne(df['flag'].shift()).cumsum())
    
    0     1
    1     1
    2     2
    3     3
    4     3
    5     3
    6     4
    7     5
    8     5
    9     6
    10    7
    11    7
    12    7
    Name: flag, dtype: int64
    

    【讨论】:

      【解决方案2】:

      通过Series.shiftSeries.cumsum 为每组的连续值创建Series,通过掩码m 仅过滤1 值,然后通过SeriesGroupBy.value_counts 计算值,max 用于按原始列映射ASeries.map:

      m = df['flag'].eq(1)
      s = df['flag'].ne(df['flag'].shift()).cumsum()[m]
      df.A.map(s.groupby(df.A).value_counts().max(level=0))
      print (df)
          A  flag  consecutive_count_max
      0   1     1                      3
      1   1     1                      3
      2   1     0                      3
      3   1     1                      3
      4   1     1                      3
      5   1     1                      3
      6   2     0                      3
      7   2     1                      3
      8   2     1                      3
      9   2     0                      3
      10  2     1                      3
      11  2     1                      3
      12  2     1                      3
      

      【讨论】:

      • 我认为 Series.maxlevel=0 的解决方案是我的解决方案,如果 OP 与标志 0 或 1 一起使用,value_counts 也不是必需的
      • @ansev - 嗯,我总是喜欢通用解决方案,所以我添加了eq(1)
      猜你喜欢
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      • 2018-11-03
      • 2018-08-25
      相关资源
      最近更新 更多