Unable to do named aggregation after groupby().count()

I have a data frame with two columns. I need to group by one of the columns, then find the group with the maximum number of rows and the name of this group. Hence I have the following code:

np.random.seed(42)
y = np.random.randint(0,5,size=(100, 2))
df = pd.DataFrame(y, columns=list('AB'))
df.groupby('A').count().agg(['max','idxmax'])

The output of this:

        B
   max  28
idxmax  3

That is, group 3 has the maximum rows in it. The maxmimum is 28.

I would like the following output, with named aggregations:

Max  ID
28   3

My attempt at a solution:

np.random.seed(42)
y = np.random.randint(0,5,size=(100, 2))
df = pd.DataFrame(y, columns=list('AB'))
df.groupby('A').count().agg(Max=('B','max'), ID=('B','idxmax'))

Which throws the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-113-dcd54f9ab49e> in <module>
      2 y = np.random.randint(0,5,size=(100, 2))
      3 df = pd.DataFrame(y, columns=list('AB'))
----> 4 df.groupby('A').count().agg(Max=('B','max'),ID=('B','idxmax'))

TypeError: aggregate() missing 1 required positional argument: 'func'

If I remove the count() function, then the named aggregation seems to work. But of course, then it’s not computing what I want to compute.

I would like to get this working, because my workaround looks quite messy:

np.random.seed(42)
y = np.random.randint(0,5,size=(100, 2))
df = pd.DataFrame(y, columns=list('AB'))
df.groupby('A').count().agg(['max','idxmax']).T.reset_index(drop=True).rename(columns={'max':'Max',
                                                                                       'idxmax':'ID'})

Output:

    Max ID
0   28  3

Pandas version 1.0.5.

Answer

Using size() rather than count() allows a small simplification:

import pandas as pd
import numpy as np

np.random.seed(42)
y = np.random.randint(0,5,size=(100, 2))
df = pd.DataFrame(y, columns=list('AB'))
df = df.groupby('A').size().agg(Max='max', ID='idxmax')
print(df)

Note that size() and count() are not identical. The size is the number of rows in each group. The count is the number of non-missing values in each column in each group. Accordingly, size() returns a Series rather than a DataFrame.

Of course, that means that after the aggregation, the output is also a Series rather than a DataFrame:

Max    28
ID      3
dtype: int64

…which you might or might not care about.