pandas DataFrame中最大值对应的列名

Vro*_*Vro 3 python dataframe python-3.x pandas

对于以下数据框数据:

x  y  a b c 
2  6 12 1 2
1  2  4 6 8
Run Code Online (Sandbox Code Playgroud)

我想要新列(即 d)的结果,该列仅在 a、b、c 之间返回具有最大值的列名称。

cols
a
c
Run Code Online (Sandbox Code Playgroud)

我试图从三列中找到最大值并返回列名。但是我不想选择数据集的所有行,而是只选择这三列的行。我使用以下代码:

def returncolname(row, colnames):
    return colnames[np.argmax(row.values)]
data['colmax'] = data.apply(lambda x: returncolname(x, data.columns), axis=1)
Run Code Online (Sandbox Code Playgroud)

cs9*_*s95 5

我能想到的最快的解决方案是DataFrame.dot

df.eq(df.max(1), axis=0).dot(df.columns)
Run Code Online (Sandbox Code Playgroud)

详细信息
首先,计算每行的最大值:

df.max(1)
0    12
1     8
dtype: int64
Run Code Online (Sandbox Code Playgroud)

接下来,找到这些值来自的位置:

df.eq(df.max(1), axis=0)     
       x      y      a      b      c
0  False  False   True  False  False
1  False  False  False  False   True
Run Code Online (Sandbox Code Playgroud)

eq用来确保跨列正确广播比较。

接下来,使用列列表计算点积:

df.eq(df.max(1), axis=0).dot(df.columns)
0    a
1    c
dtype: object
Run Code Online (Sandbox Code Playgroud)

如果最大值不是唯一的,请使用

df.eq(df.max(1), axis=0).dot(df.columns + ',').str.rstrip(',')
Run Code Online (Sandbox Code Playgroud)

获取逗号分隔的列列表。例如,

更改几个值:

df.at[0, 'c'] = 12
df.at[1, 'y'] = 8
Run Code Online (Sandbox Code Playgroud)

一切都一样,但请注意,我在每一列后面附加了一个逗号:

df.columns + ','
Index(['x,', 'y,', 'a,', 'b,', 'c,'], dtype='object')

df.eq(df.max(1), axis=0).dot(df.columns + ',')
0    a,c,
1    y,c,
dtype: object
Run Code Online (Sandbox Code Playgroud)

从这里,去掉任何尾随逗号:

df.eq(df.max(1), axis=0).dot(df.columns + ',').str.rstrip(',') 
0    a,c
1    y,c
dtype: object
Run Code Online (Sandbox Code Playgroud)


use*_*203 5

如果您不介意返回最大值的第一次出现(或者如果最大值始终是唯一的),请使用 idxmax

df[['a', 'b', 'c']].idxmax(1)
Run Code Online (Sandbox Code Playgroud)

0    a
1    c
dtype: object
Run Code Online (Sandbox Code Playgroud)

如果您需要最大值的所有出现,请使用coldspeed的答案