为 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
使用 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))
我有一个这样构建的数据库:
>>> 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
使用 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))