原始数据框:
ix x y z
0 3 4 1
1 2 0 6
2 7 1 0
3 0 0 0
应转换为:
ix x y z
0 0 1 0
1 0 0 1
2 1 0 0
3 0 0 0
如您所见,我将每一行的最大值设为1,然后将该行中的其他值设为0。此外,您还会注意到该行3
保持相同,因为它们都等于0。
因此,我已经能够使用以下方法提取最大值的索引:
x.idxmax(axis = 1)
但是我不确定如何处理最大索引。我正在考虑使用np.where,但没有可以使用的条件语句。还是我想。
任何帮助将不胜感激。
答案 0 :(得分: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
答案 1 :(得分:3)
使用:
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
答案 2 :(得分:1)
一种相当不雅的方法是:
(df.T.max() == df.T).T.astype(int)
这里,我们计算行方向最大值,然后将其与值进行比较(将其设置为True
/ False
),接下来将其转换为{{1 }}。
这将生成:
int
>>> (df.T.max() == df.T).T.astype(int)
a b c
0 0 1 0
1 0 0 1
2 1 0 0
是必需的,因为否则将计算出 columnwise 的最大值。
或者就像@AChampion所说的那样,我们可以使用.T
计算行向最大值,然后使用.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)
答案 3 :(得分:0)
您可以链接两个replace
操作
df.replace({k: [x for x in v if x!=v.max()] for k,v in df.items()}, 0).\
replace({k: v.max() for k,v in df.items()}, 1)