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

pandas在每个组中查找满足特定条件的行的索引,并为这些行赋值

  •  3
  • daiyue  · 技术社区  · 6 年前

    我有一个 df 我是说,

    name_id name
    1       a
    2       b
    2       b
    3       c
    3       c
    3       c
    

    现在我想 groupby name_id 并分配 -1 组中的行,其长度为1或<2;

        one_occurrence_indices = df.groupby('name_id').filter(lambda x: len(x) == 1).index.tolist()
    
        for index in one_occurrence_indices:
            df.loc[index, 'name_id'] = -1
    

    我想知道最好的办法是什么。所以结果 数据框 ,请

    name_id name
    -1       a
     2       b
     2       b
     3       c
     3       c
     3       c
    
    3 回复  |  直到 6 年前
        1
  •  2
  •   jezrael    6 年前

    使用 transform 具有 loc 以下内容:

    df.loc[df.groupby('name_id')['name_id'].transform('size') == 1, 'name_id'] = -1
    

    替代方案是 numpy.where 以下内容:

    df['name_id'] = np.where(df.groupby('name_id')['name_id'].transform('size') == 1, 
                             -1, df['name_id'])
    
    print (df)
       name_id name
    0       -1    a
    1        2    b
    2        2    b
    3        3    c
    4        3    c
    5        3    c
    

    如果需要测试副本,也可以使用 duplicated 以下内容:

    df['name_id'] = np.where(df.duplicated('name_id', keep=False), df['name_id'], -1)
    
        2
  •  1
  •   BENY    6 年前

    使用:

    df.name_id*=(df.groupby('name_id').name.transform(len)==1).map({True:-1,False:1})
    df
    Out[50]: 
       name_id name
    0       -1    a
    1        2    b
    2        2    b
    3        3    c
    4        3    c
    5        3    c
    
        3
  •  1
  •   jpp    6 年前

    使用 pd.DataFrame.mask 以下内容:

    lens = df.groupby('name_id')['name'].transform(len)
    
    df['name_id'].mask(lens < 2, -1, inplace=True)
    
    print(df)
    
       name_id name
    0       -1    a
    1        2    b
    2        2    b
    3        3    c
    4        3    c
    5        3    c