Пользовательский порядок сортировки для групповых панд Python - PullRequest
0 голосов
/ 08 мая 2019

Допустим, у меня есть сгруппированный фрейм данных, подобный приведенному ниже (который был получен через начальный df.groupby(df["A"]).apply(some_func), где some_func возвращает сам фрейм данных). Второй столбец - это второй уровень multiindex, который был создан groupby.

A   B C
1 0 1 8
  1 3 3
2 0 1 2
  1 2 2
3 0 1 3
  1 2 4

И я бы хотел заказать результат для пользовательской функции, которую я применяю к группам.

Давайте для этого примера предположим, что функция

def my_func(group):
    return sum(group["B"]*group["C"])

Я бы хотел, чтобы результат операции сортировки возвратил

A   B C
2 0 1 2
  1 2 2
3 0 1 3
  1 2 4
1 0 1 8
  1 3 3

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

Это основано на превосходном ответе @ Вэнь-Бена, но использует sort_values для поддержки внутренних / межгрупповых заказов.

df['func'] = (groups.apply(my_func)
              .reindex(df.index.get_level_values(0))
              .values)

(df.reset_index()
 .sort_values(['func','A','i'])
 .drop('func', axis=1)
 .set_index(['A','i']))

Примечание : алгоритм по умолчанию для idx.argsort(), quicksort, не стабильно.Вот почему ответ @ Wen-Ben не подходит для сложных наборов данных.Вы можете использовать idx.argsort(kind='mergesort') для стабильной сортировки, т. Е. Поддерживать исходный порядок в случае значений связывания.

0 голосов
/ 08 мая 2019

IIUC reindex после apply вашей функции затем выполните с argsort

idx=df.groupby('A').apply(my_func).reindex(df.index.get_level_values(0))
df.iloc[idx.argsort()]
Out[268]: 
     B  C
A       
2 0  1  2
  1  2  2
3 0  1  3
  1  2  4
1 0  1  8
  1  3  3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...