Pandas groupby类别,评级,从每个类别获得最高价值?

use*_*675 8 python dataframe pandas

关于SO的第一个问题,对熊猫来说很新,对术语仍然有些不稳定:我试图找出数据帧上正确的语法/操作顺序,以便能够按列B分组,找到最大值(或最小值) )C列中每个组的相应值,并检索A列中相应的值.

假设这是我的数据帧:

name     type      votes     
bob       dog        10
pete      cat         8
fluffy    dog         5
max       cat         9
Run Code Online (Sandbox Code Playgroud)

使用df.groupby('type').votes.agg('max')回报:

dog     10
cat      9
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.但是,我想知道如何返回:

dog    10    bob
cat     9    max 
Run Code Online (Sandbox Code Playgroud)

我已经到了df.groupby(['type', 'votes']).name.agg('max'),尽管那会回来

dog   5    fluffy
      10   bob
cat   8    pete
      9    max
Run Code Online (Sandbox Code Playgroud)

...这对于这个伪装数据帧来说很好,但在使用更大的数据帧时却没有多大帮助.

非常感谢!

unu*_*tbu 8

如果df索引没有重复值,则可以使用idxmax返回每个组的最大行索引.然后使用df.loc选择整行:

In [322]: df.loc[df.groupby('type').votes.agg('idxmax')]
Out[322]: 
  name type  votes
3  max  cat      9
0  bob  dog     10
Run Code Online (Sandbox Code Playgroud)

如果df.index有重复值,即不是唯一索引,则首先使索引唯一:

df = df.reset_index()
Run Code Online (Sandbox Code Playgroud)

然后使用idxmax:

result = df.loc[df.groupby('type').votes.agg('idxmax')]
Run Code Online (Sandbox Code Playgroud)

如果你真的需要,你可以回到df原来的状态:

df = df.set_index(['index'], drop=True)
Run Code Online (Sandbox Code Playgroud)

但总的来说,一个独特的指数会让生活变得更好.


这是一个显示df没有唯一索引时出错的示例.假设indexAABB:

import pandas as pd
df = pd.DataFrame({'name': ['bob', 'pete', 'fluffy', 'max'],
                   'type': ['dog', 'cat', 'dog', 'cat'],
                   'votes': [10, 8, 5, 9]}, 
                  index=list('AABB'))
print(df)
#      name type  votes
# A     bob  dog     10
# A    pete  cat      8
# B  fluffy  dog      5
# B     max  cat      9
Run Code Online (Sandbox Code Playgroud)

idxmax返回索引值AB:

print(df.groupby('type').votes.agg('idxmax'))
type
cat    B
dog    A
Name: votes, dtype: object
Run Code Online (Sandbox Code Playgroud)

但是AB没有唯一地指定所需的行.df.loc[...] 返回索引值为A或的所有行B:

print(df.loc[df.groupby('type').votes.agg('idxmax')])
#      name type  votes
# B  fluffy  dog      5
# B     max  cat      9
# A     bob  dog     10
# A    pete  cat      8
Run Code Online (Sandbox Code Playgroud)

相反,如果我们重置索引:

df = df.reset_index()
#   index    name type  votes
# 0     A     bob  dog     10
# 1     A    pete  cat      8
# 2     B  fluffy  dog      5
# 3     B     max  cat      9
Run Code Online (Sandbox Code Playgroud)

然后df.loc可以用来选择所需的行:

print(df.groupby('type').votes.agg('idxmax'))
# type
# cat    3
# dog    0
# Name: votes, dtype: int64

print(df.loc[df.groupby('type').votes.agg('idxmax')])
#   index name type  votes
# 3     B  max  cat      9
# 0     A  bob  dog     10
Run Code Online (Sandbox Code Playgroud)