Pandas groupby агрегат, передавая имя группы в агрегат - PullRequest
0 голосов
/ 08 мая 2018

В общем шаблоне использования мне нужно агрегировать DataFrame, используя пользовательскую функцию агрегирования. В этом особом случае статистическая функция должна знать текущую группу для того, чтобы правильно выполнить агрегацию.

Функция, переданная в DataFrameGroupBy.aggregate(), вызывается для каждой группы и для каждого столбца, получая Series с элементами в текущей группе и столбце. Единственный способ найти имя группы внутри агрегатной функции - добавить столбец группировки в индекс, а затем извлечь значение с помощью x.index.get_level_values('power')[0]. Вот пример:

def _tail_mean_user_th(x):
    power = x.index.get_level_values('power')[0]
    th = th_dict[power]  # this values changes with the group
    return x.loc[x > th].mean() - th

mbsize_df = (bursts_sel.set_index('power', append=True).groupby('power')
             .agg({'nt': _tail_mean_user_th}))

Мне кажется, что агрегатная функция должна знать текущую группу довольно часто. Есть ли более простой шаблон в этой ситуации?


EDIT : Решение, которое я принял ниже, заключается в использовании apply вместо agg в объекте GroupBy. Разница между ними заключается в том, что agg вызывает функцию для каждой группы и каждого столбца в отдельности, а apply вызывает функцию для каждой группы (все столбцы одновременно). Тонким следствием этого является то, что agg передаст Series для текущей группы и столбца с атрибутом name, равным исходному имени столбца. И наоборот, apply передаст Series с атрибутом name, равным текущей группе (что было моим вопросом). Интересно, что при работе с несколькими столбцами apply будет передавать DataFrame с атрибутом name (обычно отсутствующим для DataFrames), установленным в имя группы. Так что этот шаблон также работает при объединении нескольких столбцов одновременно.

Для получения дополнительной информации см. В чем разница между Pandas Agg и функцией применения?

1 Ответ

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

Если вы используете groupby + apply, тогда он доступен через атрибут .name:

df = pd.DataFrame({'a': [1, 2, 1, 2], 'b': [1, 1, 2, 2]})
def foo(g):
    print('at group %s' % g.name)
    return int(g.name) + g.sum()    

>>> df.b.groupby(df.a).apply(foo)
at group 1
at group 2
a
1    4
2    5
Name: b, dtype: int64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...