为 Pandas 中的 n 个最大值生成虚拟变量

generating dummy variables for n largest values in Pandas

我有一个这样构建的数据库:

>>> df = pd.DataFrame({'id':[1,1,1,2,2,2,2,3,4],'value':[1,2,3,1,2,3,4,1,1]})

>>> df

    id  value    
0   1      1    
1   1      2    
2   1      3    
3   2      1    
4   2      2    
5   2      3    
6   2      4    
7   3      1    
8   4      1

并且我想为每个 ID 的第 n 个最大值生成一个虚拟变量(此处为 n=2),以便对于第 n 个最大值之一的所有值都等于 1:

    id  value  Largest 
0   1      1     0    
1   1      2     1    
2   1      3     1    
3   2      1     0    
4   2      2     0    
5   2      3     1    
6   2      4     1    
7   3      1     1    
8   4      1     1

我试过:

df['highest'] = 0
df['highest'].loc[df['value'].isin(df.groupby(['id'])['value'].nlargest(1))] = 1

但是如果一个 ID 的值恰好是另一个 ID 中的最高值,那么这将误认为另一个 ID 中的值

设置

df = pd.DataFrame({'id':[1,1,1,2,2,2,2,3,4],'value':[1,2,3,1,2,3,4,1,1]})
n = 2

使用 nlargestloc:

df['flag'] = 0
df.loc[df.groupby('id').value.nlargest(n).index.get_level_values(1), 'flag'] = 1

使用 np.whereassign:

这避免了就地修改 DataFrame。

df.assign(
    flag=np.where(
        df.index.isin(df.groupby('id').value.nlargest(n).index.get_level_values(1)), 1, 0
    )
)

两者都导致:

   id  value  flag
0   1      1     0
1   1      2     1
2   1      3     1
3   2      1     0
4   2      2     0
5   2      3     1
6   2      4     1
7   3      1     1
8   4      1     1

正如@jezrael 指出的那样,np.where 在这里并不是必需的,因为您正在寻找二进制结果,您可以改用:

df.assign(flag=df.index.isin(df.groupby('id').value.nlargest(n).index.get_level_values(1)).astype(int))