Функции GroupBy в Python Pandas, такие как SUM (col 1*col 2), weighted average и т. д
Можно ли непосредственно вычислить произведение (или, например, сумму) двух столбцов без использования
grouped.apply(lambda x: (x.a*x.b).sum()
Это намного (менее половины времени на моей машине) быстрее использовать
df['helper'] = df.a*df.b
grouped= df.groupby(something)
grouped['helper'].sum()
df.drop('helper', axis=1)
Но мне не очень нравится делать это.
Например, полезно вычислить средневзвешенное значение для каждой группы. Здесь лямбда-подход будет
grouped.apply(lambda x: (x.a*x.b).sum()/(df.b).sum())
И опять же гораздо медленнее, чем деление помощника на b. sum ().
3 ответов:
Я хочу со временем построить встроенный вычислитель выражений массива (Numexpr на стероидах), чтобы делать такие вещи. Прямо сейчас мы работаем с ограничениями Python - если вы реализовали агрегатор Cython для выполнения
(x * y).sum(), то он может быть связан с groupby, но в идеале вы можете написать выражение Python как функцию:def weight_sum(x, y): return (x * y).sum()И это будет "JIT-compiled" и будет примерно так же быстро, как groupby(...).сумма(). То, что я описываю, - довольно значительный (многомесячный) проект. Если существовала BSD-совместимая реализация APL, которую я мог бы сделать немного раньше (просто думая вслух).
Как насчет прямой группировки результата x. a*x. b, например:
from pandas import * from numpy.random import randn df = DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'], 'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'C' : randn(8), 'D' : randn(8)}) print (df.C*df.D).groupby(df.A).sum()
Ответ пришел много лет спустя через pydata blaze
from blaze import * data = Data(df) somethings = odo( by(data.something, wm = (data.a * data.weights).sum()/data.weights.sum()), pd.DataFrame)
Comments