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
  • 379,657
  • 97
  • 704
  • 746
Giora Simchoni
  • 3,487
  • 3
  • 34
  • 72

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
  • 317,841
  • 20
  • 164
  • 234
6
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,303
  • 9
  • 24
5

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
  • 379,657
  • 97
  • 704
  • 746
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
  • 50,081
  • 9
  • 65
  • 94