代码之家  ›  专栏  ›  技术社区  ›  theletz

包含最接近的较大值的类别

  •  1
  • theletz  · 技术社区  · 4 年前

    我有以下数据帧:

    df = pd.DataFrame({'id': ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c','c','c'], 'cumsum': [1, 3, 6, 9, 10, 4, 9, 11, 13, 5, 8, 19]})
    
    
       id   cumsum
    0   a   1
    1   a   3
    2   a   6
    3   a   9
    4   a   10
    5   b   4
    6   b   9
    7   b   11
    8   b   13
    9   c   5
    10  c   8
    11  c   19
    

    我想得到一个新的列,其中包含一个类别,这样,对于一个特定的输入,对于每个 id 它将取最接近的较大(或相等)值作为第一个类别。

    例如:

    input = 8
    

    期望输出:

        id  cumsum  category
    0   a   1   0
    1   a   3   0
    2   a   6   0
    3   a   9   0
    4   a   10  1
    5   b   4   0
    6   b   10  0
    7   b   11  1
    8   b   13  1
    9   c   5   0
    10  c   8   0
    11  c   19  1
    
    1 回复  |  直到 4 年前
        1
  •  1
  •   jezrael    4 年前

    您可以通过输入获得第一个大于等于的值 GroupBy.first 并按 Series.ge ,然后比较 Series.gt 映射值依据 Series.map 具有 Id 最后将掩码转换为整数:

    val = 8
    
    s = df[df['cumsum'].ge(val)].groupby('id')['cumsum'].first()
    
    df['category'] = df['cumsum'].gt(df['id'].map(s)).astype(int)
    print (df)
       id  cumsum  category
    0   a       1         0
    1   a       3         0
    2   a       6         0
    3   a       9         0
    4   a      10         1
    5   b       4         0
    6   b       9         0
    7   b      11         1
    8   b      13         1
    9   c       5         0
    10  c       8         0
    11  c      19         1
    

    另一个想法是使用 Series.where 具有 GroupBy.transform :

    val = 8
    
    s1 = df['cumsum'].where(df['cumsum'].ge(val)).groupby(df['id']).transform('min')
    #alternative
    s1 = df['cumsum'].where(df['cumsum'].ge(val)).groupby(df['id']).transform('first')
    
    df['category'] =  df['cumsum'].gt(s1).astype(int)