Как выполнить взвешенное среднее каждые 2 строки в Pandas? - PullRequest
0 голосов
/ 20 января 2019

Мои данные выглядят так:

...
                     A         B      C
2017-09-18 12:00:00  1.000010  18000  100
2017-09-18 17:00:00  1.000029  13500  400
2017-09-19 12:00:00  1.000025  18000  300
2017-09-19 17:00:00  1.000037  13500  300

...

В два разных дня в один и тот же день принимаются меры A, B и C.

Мне нужно свернуть каждые 2 меры /число дней в одной строке (например, для первых 2 строк):

  • средневзвешенное значение столбцов A и B

    ((A1 * B1) + (A2 * B2)) / (B1 + B2)

  • среднее значение столбца C

    (C1 + C2) / 2

Моя трудность возникает при попытке df.groupby этих соседних строк, учитывая, что они имеют различныевремя и необходимость выполнения пользовательской операции для столбцов AB, которая отличается от C.

Мой ожидаемый результат будет:

                     A            C
2017-09-18 12:00:00  1.000018143  250
2017-09-19 12:00:00  1.000030143  300

Любые указатели будут с благодарностью.

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Вы можете векторизовать это с помощью groupby, apply и mean:

def AB_weighted(g):
   return (g['A'] * g['B']).sum() / g['B'].sum()

g = df.groupby(df.index.date)
pd.concat([g.apply(AB_weighted), g['C'].mean()], keys=['A', 'C'], axis=1)

                   A    C
2017-09-18  1.000018  250
2017-09-19  1.000030  300
  • Нам нужно apply для первого условия, поскольку при групповом вычислении используются несколько столбцов - «A» и «B».
  • Для вычисления среднего значения «C» требуется только «C», поэтому мы можем сократить число с помощью mean().

Другим вариантом является вычисление продукта до groupby, поэтому мы можем обойти вызов на apply (это немного похоже на @ W-B второй ответ), но с одним вызовом sum.

u = df.assign(D=df['A'] * df['B'])[['D', 'B']].groupby(df.index.date).sum()
u['A'] = u.pop('D') / u.pop('B')

u['C'] = df.groupby(df.index.date)['C'].mean()

u
                   A    C
2017-09-18  1.000018  250
2017-09-19  1.000030  300
0 голосов
/ 20 января 2019

Проверьте с

df.groupby(df.index.date).apply(lambda x : pd.Series({'A':sum(x['A']*x['B'])/sum(x['B']),'C':(x['C']).mean()}))
                   A      C
2017-09-18  1.000018  250.0
2017-09-19  1.000030  300.0

Или давайте не будем применять

t1=df.eval('A*B').groupby(df.index.date).sum()/df.groupby(df.index.date).B.sum()
t2=df.groupby(df.index.date).C.mean()

pd.concat([t1,t2],1)
                   0    C
2017-09-18  1.000018  250
2017-09-19  1.000030  300
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...