Для первой части вы можете передать имя столбца для ключей и список функций для значений:
In [28]: df
Out[28]:
A B C D E GRP
0 0.395670 0.219560 0.600644 0.613445 0.242893 0
1 0.323911 0.464584 0.107215 0.204072 0.927325 0
2 0.321358 0.076037 0.166946 0.439661 0.914612 1
3 0.133466 0.447946 0.014815 0.130781 0.268290 1
In [26]: f = {'A':['sum','mean'], 'B':['prod']}
In [27]: df.groupby('GRP').agg(f)
Out[27]:
A B
sum mean prod
GRP
0 0.719580 0.359790 0.102004
1 0.454824 0.227412 0.034060
UPDATE 1:
Поскольку агрегатная функция работает над Series, ссылки на другие имена столбцов теряются. Чтобы обойти это, вы можете ссылаться на полный фреймворк и индексировать его с помощью индексов группы в лямбда-функции.
Вот хакерский способ обхода:
In [67]: f = {'A':['sum','mean'], 'B':['prod'], 'D': lambda g: df.loc[g.index].E.sum()}
In [69]: df.groupby('GRP').agg(f)
Out[69]:
A B D
sum mean prod <lambda>
GRP
0 0.719580 0.359790 0.102004 1.170219
1 0.454824 0.227412 0.034060 1.182901
Здесь результирующий ' D 'состоит из суммированных значений «E».
UPDATE 2:
Вот такой метод, который, я думаю, сделает все, что вы просите. Сначала создайте пользовательскую лямбда-функцию. Ниже, g ссылается на группу. При агрегировании g будет Серией. Передача g.index
в df.ix[]
позволяет выбрать текущую группу из df. Затем я тестирую, если столбец C меньше 0,5. Возвращенная логическая серия передается в g[]
, которая выбирает только те строки, которые соответствуют критериям.
In [95]: cust = lambda g: g[df.loc[g.index]['C'] < 0.5].sum()
In [96]: f = {'A':['sum','mean'], 'B':['prod'], 'D': {'my name': cust}}
In [97]: df.groupby('GRP').agg(f)
Out[97]:
A B D
sum mean prod my name
GRP
0 0.719580 0.359790 0.102004 0.204072
1 0.454824 0.227412 0.034060 0.570441