我有一个这样构建的数据库:
>>> 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中的值
答案 0 :(得分:4)
设置
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
nlargest
和loc
:df['flag'] = 0
df.loc[df.groupby('id').value.nlargest(n).index.get_level_values(1), 'flag'] = 1
np.where
和assign
:这避免了就地修改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))