3 回答

TA贡献2011条经验 获得超2个赞
用:
df.eq(df.where(df != 0).max(1), axis=0).astype(int)
df
x y z
ix
0 3.0 4.0 1.0
1 2.0 1.0 6.0
2 7.0 1.0 6.0
3 0.0 0.0 0.0
4 4.0 0.0 4.0
输出:
x y z
ix
0 0 1 0
1 0 0 1
2 1 0 0
3 0 0 0
4 1 0 1
另一种方法使用rank:
df.where(df!=0).rank(1, ascending=False, method='dense').eq(1).astype(int)
输出:
x y z
ix
0 0 1 0
1 0 0 1
2 1 0 0
3 0 0 0
4 1 0 1

TA贡献1868条经验 获得超4个赞
首先,找到数据框中具有非零行的部分。然后找到最大值并将它们与矩阵进行比较:
affected = (df != 0).any(axis=1)
nz = df[affected]
df[affected] = (nz.T == nz.max(axis=1)).T.astype(int)
# x y z
#0 0 1 0
#1 0 0 1
#2 1 0 0
#3 0 0 0

TA贡献1773条经验 获得超3个赞
做到这一点的一种不太雅致的方法是:
(df.T.max() == df.T).T.astype(int)
在这里,我们计算按行的最大值,然后将其与值进行比较(将其设置为True/ False),然后将其转换为ints。
这将产生:
>>> (df.T.max() == df.T).T.astype(int)
a b c
0 0 1 0
1 0 0 1
2 1 0 0
该.T是必要的,因为这将另有计算纵列最大。
或就像@AChampion所说的那样,我们可以使用计算行的最大值,.max(axis=1)然后使用df.eq(..)来计算行的相等性。喜欢:
>>> df.eq(df.max(axis=1), axis=0).astype(int)
a b c
0 0 1 0
1 0 0 1
2 1 0 0
编辑:仅更新非零行
例如,我们可以使用屏蔽来防止将这些值分配给零行。例如:
fl = (df != 0).any(axis=1)
df[fl] = df[fl].eq(df[fl].max(axis=1), axis=0).astype(int)
例如:
>>> df = pd.DataFrame([[3, 4, 1], [2, 1, 6], [7, 1, 6], [0, 0, 0]], columns=["a", "b", "c"])
>>> fl = (df != 0).any(axis=1)
>>> df[fl] = df[fl].eq(df[fl].max(axis=1), axis=0).astype(int)
>>> df
a b c
0 0 1 0
1 0 0 1
2 1 0 0
3 0 0 0
添加回答
举报