在 pandas 数据框中排序的水平查找

Horizontal lookup with sorted in pandas dataframe

我创建了这个 pandas 数据框:

d = {'Char1': [-3,2,0], 'Char2': [0,1,2], 'Char3': [-1,0,-1]}
df = pd.DataFrame(data=d)
print(df)

看起来像这样:

我需要创建两个附加字段:

这是 Factor1 和 Factor2 在每条记录中的填充方式:

因此,生成的数据集应如下所示:

那么,让我们看一下第一条记录:

以此类推

如何在 Python/Pandas 中执行此操作?

您可以通过

获得跨列的最小值
df['Factor1'] = df.idxmin(axis="columns")

然后,您可以在每列中添加最小值以再次获得最小值,或者应用掩码以删除已经采用的值

你可以做到 idxmin 并且为了获得第二小我们可以 mask min

out = df.assign( **{'factor1' : df.idxmin(1), 
                    'factor2' : df.mask(df.eq(df.min(1),axis=0)).idxmin(1)})
Out[28]: 
   Char1  Char2  Char3 factor1 factor2
0     -3      0     -1   Char1   Char3
1      2      1      0   Char3   Char2
2      0      2     -1   Char3   Char1

一种有效的方法是使用底层 numpy 数组 argsort:

import numpy as np

df[['Factor1', 'Factor2']] = df.columns.to_numpy()[np.argsort(df.to_numpy())[:, :2]]

输出:

   Char1  Char2  Char3 Factor1 Factor2
0     -3      0     -1   Char1   Char3
1      2      1      0   Char3   Char2
2      0      2     -1   Char3   Char1
泛化到 N 列:
import numpy as np

N = 2

order = np.argsort(df.to_numpy())[:, :N]
df[[f'Factor{i+1}' for i in range(N)]] = df.columns.to_numpy()[order]

N=3 的示例:

   Char1  Char2  Char3 Factor1 Factor2 Factor3
0     -3      0     -1   Char1   Char3   Char2
1      2      1      0   Char3   Char2   Char1
2      0      2     -1   Char3   Char1   Char2