Select top n items in a pandas groupby and calculate the mean

I have the following dataframe:

df = pd.DataFrame({'Value': [0, 1, 2,3, 4,5,6,7,8,9],'Name': ['John', 'Jim', 'John','Jim', 'John','Jim','Jim','John','Jim','John']})
df
    Value   Name
0   0   John
1   1   Jim
2   2   John
3   3   Jim
4   4   John
5   5   Jim
6   6   Jim
7   7   John
8   8   Jim
9   9   John

I would like to select the top n items by Name and find the mean from the Value column.

I have tried this:

df['Top2Mean'] = df.groupby(['Name'])['Value'].nlargest(2).transform('mean')

But the following error:

ValueError: transforms cannot produce aggregated results

My expected result is a new column called Top2Mean with a 8 next to John and 7 next to Jim.

Thanks in advance!

Answer

Let us calculate mean on level=0, then map the calculated mean value to the Name column to broadcast the aggregated results.

top2 = df.groupby('Name')['Value'].nlargest(2).mean(level=0)
df['Top2Mean'] = df['Name'].map(top2)

If we need to group on multiple columns for example Name and City then we have to take mean on level=[Name, City] and map the calculated mean values using MultiIndex.map

c = ['Name', 'City']
top2 = df.groupby(c)['Value'].nlargest(2).mean(level=c)
df['Top2Mean'] = df.set_index(c).index.map(top2)

Alternative approach with groupby and transform using a custom lambda function

df['Top2Mean'] = df.groupby('Name')['Value']
                   .transform(lambda v: v.nlargest(2).mean())

   Value  Name  Top2Mean
0      0  John         8
1      1   Jim         7
2      2  John         8
3      3   Jim         7
4      4  John         8
5      5   Jim         7
6      6   Jim         7
7      7  John         8
8      8   Jim         7
9      9  John         8