Python 为特定列优化的行索引

Python 为特定列优化的行索引,python,pandas,Python,Pandas,我有一个dataframe示例,如下所示 p1 p2 p3 score 0 1 a t1 0.408718 1 1 a t2 0.694732 2 1 a t3 0.001077 3 1 b t1 0.250646 4 1 b t2 0.877506 5 1 b t3 0.033305 6 2 a t1 0.735524 7 2 a t2 0.055166 8 2

我有一个dataframe示例,如下所示

   p1   p2  p3  score
0   1   a   t1  0.408718
1   1   a   t2  0.694732
2   1   a   t3  0.001077
3   1   b   t1  0.250646
4   1   b   t2  0.877506
5   1   b   t3  0.033305
6   2   a   t1  0.735524
7   2   a   t2  0.055166
8   2   a   t3  0.579875
9   2   b   t1  0.579199
10  2   b   t2  0.785301
11  2   b   t3  0.339372
temp = []
for eachgroup in df.groupby(['p1', 'p2']).groups.keys():
    temp.append(df.groupby(['p1', 'p2']).get_group(eachgroup)['score'])

temp1 = []
for each in temp:
temp1.append(each.mean())

maxidx = temp1.index(max(temp1))

temp[maxidx].index
p1、p2和p3是参数。我想做的是选择具有p1和p2值的最佳行,其最大平均分数基于p3

例如,在给定的数据帧中,此函数应返回第9、10、11行中的任意一行,因为p3得分的平均值0.579199、0.785301、0.339372=0.567958是任何给定p1和p2集的最大值

到目前为止,我使用pandas groupy的尝试如下

   p1   p2  p3  score
0   1   a   t1  0.408718
1   1   a   t2  0.694732
2   1   a   t3  0.001077
3   1   b   t1  0.250646
4   1   b   t2  0.877506
5   1   b   t3  0.033305
6   2   a   t1  0.735524
7   2   a   t2  0.055166
8   2   a   t3  0.579875
9   2   b   t1  0.579199
10  2   b   t2  0.785301
11  2   b   t3  0.339372
temp = []
for eachgroup in df.groupby(['p1', 'p2']).groups.keys():
    temp.append(df.groupby(['p1', 'p2']).get_group(eachgroup)['score'])

temp1 = []
for each in temp:
temp1.append(each.mean())

maxidx = temp1.index(max(temp1))

temp[maxidx].index
返回以下输出

Int64Index([9, 10, 11], dtype='int64')
然而,这是非常低效的,并且只适用于较小的数据帧。如何对较大的数据帧执行相同操作?

使用groupby和transform:

如果您希望p1和p2的组合与此最大值对应:

>>> df.groupby(['p1', 'p2']).score.mean().idxmax()
(2, 'b')
如果您想查看创建最大平均值的范围,后者将非常有用:

df.set_index(['p1', 'p2']).loc[(2, 'b')]

       p3     score
p1 p2
2  b   t1  0.579199
   b   t2  0.785301
   b   t3  0.339372
就你而言

s=df.groupby(['p1','p2']).score.transform('mean')
s.index[s==s.max()]
Out[239]: Int64Index([9, 10, 11], dtype='int64')

一行:根据p1和p2分组,取每组得分列的平均值。获取聚合序列中最大值的id

df.groupby(['p1', 'p2'])['score'].agg(lambda x: x.mean()).idxmax()

>>> ('2', 'b')

这是一条非常优雅的单行线。谢谢。如果您想要与最大值对应的所有行。如果你只是对p1和p2的组合感兴趣,你只需要一行,一行就能给出p1和p2的最佳值。因此,在我的例子中,这是一个简单、简洁、高效的方法,同时保持清晰一致。非常简洁和优雅。谢谢