我有一个像下面这样的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
基于行的总和也不会产生预期的结果,因为它不区分类别。
答案 0 :(得分:2)
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
答案 1 :(得分:1)
这个怎么样
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