Pandas DataFrame 获取列组合最大值

Pandas DataFrame get column combined max values

我有一个 pandas DataFrame,如下所示。

df = pd.DataFrame({"A": [3,1,2,4,5,3,4,10], "B": [1,3,2,4,0,0,1,0]})

行值 0 到 10 是建议(10 是最好的)。一个 DataFrame 列是与 0 到 10 推荐相关的类别(A、B 等)。所有类别的权重相同,但每一行都与一项相关。

我希望 DataFrame 对最大值组合到 (或更多)类别的项目进行排序。因此,如果与某个项目相关的行在类别 A 中的值为 10,但在类别 B 中的值为 0,则这不是最高评分项目的预期解决方案。在上面给出的示例中,值为 [4,4] 的行将是最佳选择。

我的 groupby 解决方案没有给出预期的结果。

grouped = df.groupby(['A', 'B'])
grouped[["A", "B"]].max().sort(ascending=False)

结果:

        A   B
A   B       
10  2   10  0
5   0   5   0
4   4   4   4
    1   4   1
3   1   3   1
    0   3   0
2   2   2   2
1   3   1   3

基于行的总和也不会产生预期的结果,因为它不区分类别。

这个怎么样

df['pos'] = df.A/df.A.mean() + df.B/df.B.mean()
df.sort( columns='pos', ascending=False)

#    A  B       pos
#3   4  4  3.909091
#7  10  0  2.500000
#1   1  3  2.431818
#2   2  2  1.954545
#6   4  1  1.727273
#0   3  1  1.477273
#4   5  0  1.250000
#5   3  0  0.750000

如果您有更多要排名的列 ['A','B','C', ...]

cols = ['A','B'] # ,'C', 'D', ... ]
df['pos'] = pandas.np.sum([ df[col]/df[col].mean() for col in cols ],axis=0)

更新

因为 0 被认为是质量值(最低),所以我会按如下方式修改我的答案(不确定是否会产生巨大差异)

df['pos'] = (df.A+1)/(df.A.max()+1) + (df.B+1)/(df.B.max()+1)
df.sort( columns='pos', ascending=False)
#    A  B       pos
#3   4  4  1.454545
#7  10  0  1.200000
#1   1  3  0.981818
#2   2  2  0.872727
#6   4  1  0.854545
#0   3  1  0.763636
#4   5  0  0.745455
#5   3  0  0.563636
df = pd.DataFrame({"A": [3,1,2,4,5,3,4,10], "B": [1,3,2,4,0,0,1,0]})

然后计算数据框中每一列的排名

rank = df.rank(method = "dense")
rank

Out[44]:
    A   B
0   3   2
1   1   4
2   2   3
3   4   5
4   5   1
5   3   1
6   4   2
7   6   1

向数据框添加一个新列,这是基于所有类别的总排名

df['total_rank'] = rank.sum(axis = 1)
df


Out[46]:
    A   B   total_rank
0   3   1   5
1   1   3   5
2   2   2   5
3   4   4   9
4   5   0   6
5   3   0   4
6   4   1   6
7   10  0   7

最后按总排名对数据框进行排序

df.sort(columns='total_rank' , ascending = False)


Out[49]:
    A   B   total_rank
3   4   4   9
7   10  0   7
4   5   0   6
6   4   1   6
0   3   1   5
1   1   3   5
2   2   2   5
5   3   0   4