Необходимо создать вспомогательный столбец для сортировки, в данном случае size
групп имен.Добавьте .reset_index(drop=True)
, если вы предпочитаете новый RangeIndex, или оставьте как есть, если оригинальный индекс полезен.
Сортировка не меняет порядок в пределах одинаковых значений, поэтому всегда будет появляться первая строка 'Paul'
сначала внутри 'Paul'
(df.assign(s = df.groupby('name').name.transform('size'))
.sort_values('s', ascending=False)
.drop(columns='s'))
Вывод
name age
0 Paul 12
3 Paul 36
4 Paul 66
2 Michael 100
5 Michael 45
1 Ryan 17
Чтобы развеять опасения, высказанные в комментариях, этот метод является быстродействующим.Гораздо больше, чем вышеупомянутый метод.Кроме того, вы не портите свой начальный индекс.
import numpy as np
np.random.seed(42)
N = 10**6
df = pd.DataFrame({'name': np.random.randint(1, 10000, N),
'age': np.random.normal(0, 1, N)})
%%timeit
(df.assign(s = df.groupby('name').name.transform('size'))
.sort_values('s', ascending=False)
.drop(columns='s'))
#500 ms ± 31.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
x = list(df['name'].value_counts().index)
df.set_index('name').loc[x].reset_index()
#2.67 s ± 166 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)