在 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)
看起来像这样:
我需要创建两个附加字段:
- 因素 1
- 因子 2
这是 Factor1 和 Factor2 在每条记录中的填充方式:
- Factor1 应包含具有最低值的列的名称(同样,跨每条记录);
- Factor2 应包含具有第二小值的列的名称(同样,跨每条记录)。
因此,生成的数据集应如下所示:
那么,让我们看一下第一条记录:
- 最低值是多少?是-3
- -3 对应的列的名称是什么?它是 Char1 -> "Char1" 然后分配给 Factor1
- 第二低的值是多少?是-1
- -1 对应的列的名称是什么?它是 Char3 -> "Char3" 然后分配给 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
我创建了这个 pandas 数据框:
d = {'Char1': [-3,2,0], 'Char2': [0,1,2], 'Char3': [-1,0,-1]}
df = pd.DataFrame(data=d)
print(df)
看起来像这样:
我需要创建两个附加字段:
- 因素 1
- 因子 2
这是 Factor1 和 Factor2 在每条记录中的填充方式:
- Factor1 应包含具有最低值的列的名称(同样,跨每条记录);
- Factor2 应包含具有第二小值的列的名称(同样,跨每条记录)。
因此,生成的数据集应如下所示:
那么,让我们看一下第一条记录:
- 最低值是多少?是-3
- -3 对应的列的名称是什么?它是 Char1 -> "Char1" 然后分配给 Factor1
- 第二低的值是多少?是-1
- -1 对应的列的名称是什么?它是 Char3 -> "Char3" 然后分配给 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