7

Simple DataFrame:

df = pd.DataFrame({'A': [1,1,2,2], 'B': [0,1,2,3], 'C': ['a','b','c','d']})
df
   A  B  C
0  1  0  a
1  1  1  b
2  2  2  c
3  2  3  d

I wish for every value (groupby) of column A, to get the value of column C, for which column B is maximum. For example for group 1 of column A, the maximum of column B is 1, so I want the value "b" of column C:

   A  C
0  1  b
1  2  d

No need to assume column B is sorted, performance is of top priority, then elegance.

cs95
  • 330,695
  • 80
  • 606
  • 657
Giora Simchoni
  • 3,057
  • 3
  • 30
  • 64

4 Answers4

9

Check with sort_values +drop_duplicates

df.sort_values('B').drop_duplicates(['A'],keep='last')
Out[127]: 
   A  B  C
1  1  1  b
3  2  3  d
BENY
  • 296,997
  • 19
  • 147
  • 204
5
df.groupby('A').apply(lambda x: x.loc[x['B'].idxmax(), 'C'])
#    A
#1    b
#2    d

Use idxmax to find the index where B is maximal, then select column C within that group (using a lambda-function

Jondiedoop
  • 3,174
  • 8
  • 23
4

Here's a little fun with groupby and nlargest:

(df.set_index('C')
   .groupby('A')['B']
   .nlargest(1)
   .index
   .to_frame()
   .reset_index(drop=True))

   A  C
0  1  b
1  2  d

Or, sort_values, groupby, and last:

df.sort_values('B').groupby('A')['C'].last().reset_index()

   A  C
0  1  b
1  2  d
cs95
  • 330,695
  • 80
  • 606
  • 657
2

Similar solution to @Jondiedoop, but avoids the apply:

u = df.groupby('A')['B'].idxmax()

df.loc[u, ['A', 'C']].reset_index(drop=1)

   A  C
0  1  b
1  2  d
user3483203
  • 48,205
  • 9
  • 52
  • 84