Панды: Calc.средневзвешенная цена, с использованием groupby / lambda или функции - PullRequest
0 голосов
/ 13 октября 2018

У меня есть DataFrame, где 4 уникальных ордера разбиты на строки 3-12.Как вы можете видеть ниже в шагах 1, 2 и 3, я использую groupby, чтобы сделать так, чтобы 1 ордер = 1 строка.

Однако мне не хватает одного важного шага, вычисляя средневзвешенную цену для каждого ордера.В настоящее время вместо шага 2 рассчитывается средняя цена.

Что я хочу сделать:

Создать функцию / лямбду, которая может рассчитать средневзвешенную цену для каждого ордера (возможно на основе группового столбца «Время»).


  • Порядок 1 = Строка 3, 4
  • Порядок 2 = Строка 5, 6, 7
  • Заказ 3 = строка 8, 9
  • Заказ 4 = строка 10, 11, 10

Формула для средневзвешенной цены = ((первая цена * сумма)+ (вторая цена * сумма)) / общая сумма

Средневзвешенная цена для заказа 1 = ((660,33 * 0,0130) + (659,58 * 0,0070)) / 0,02 = 660,06750

Шаг 1 - Исходный фрейм данных:

| 1| Time      | Market    | Type  | Price    | Amount  | Total    | Fee      | Acc     |
| 2|-----------|-----------|-------|----------|---------|----------|----------|---------|
| 3| 22:12:15  | Market 1  | Buy   | 660.33   | 0.0130  | 8.58429  | 0.00085  | MXG_33  |
| 4| 22:12:15  | Market 1  | Buy   | 659.58   | 0.0070  | 4.61706  | 0.00055  | MXG_33  |
| 5| 19:36:08  | Market 1  | Sell  | 670.00   | 0.0082  | 5.49400  | 0.00070  | MXG_33  |
| 6| 19:36:08  | Market 1  | Sell  | 670.33   | 0.0058  | 3.88791  | 0.00048  | MXG_33  |
| 7| 19:36:08  | Market 1  | Sell  | 671.23   | 0.0060  | 4.02738  | 0.00054  | MXG_33  |
| 8| 13:01:41  | Market 1  | Buy   | 667.15   | 0.0015  | 1.00073  | 0.00011  | MXG_33  |
| 9| 13:01:41  | Market 1  | Buy   | 667.10   | 0.0185  | 12.3414  | 0.00132  | MXG_33  |
|10| 07:14:36  | Market 1  | Sell  | 657.55   | 0.0107  | 7.03579  | 0.00079  | MXG_33  |
|11| 07:14:36  | Market 1  | Sell  | 657.08   | 0.0005  | 0.32854  | 0.00004  | MXG_33  |
|12| 07:14:36  | Market 1  | Sell  | 656.59   | 0.0088  | 5.77799  | 0.00071  | MXG_33  |

Шаг 2: Объединение заказов обратно в 1-й ряд pr pr:

d_agg = {'Market':'first'
    ,'Type':'first'
    ,'Price':'mean'
    ,'Amount':'sum'
    ,'Total':'sum'
    ,'Fee':'sum'
    ,'Acc':'first'}


(df.groupby('Time', sort=False)['Market','Type','Price','Amount','Total','Fee','Acc'].agg(d_agg).reset_index())

Шаг 3- Окончательный результат: (но столбец «Цена» показывает средние цены вместо средневзвешенных).

| 1| Time      | Market    | Type  | Price    | Amount  | Total     | Fee      | Acc     |
| 2|-----------|-----------|-------|----------|---------|-----------|----------|---------|
| 3| 22:12:15  | Market 1  | Buy   | 659.955  | 0.0200  | 13.20135  | 0.00140  | MXG_33  |
| 4| 19:36:08  | Market 1  | Sell  | 670.520  | 0.0200  | 13.40929  | 0.00172  | MXG_33  |
| 5| 13:01:41  | Market 1  | Buy   | 667.125  | 0.0200  | 13.34213  | 0.00242  | MXG_33  |
| 6| 07:14:36  | Market 1  | Sell  | 657.073  | 0.0200  | 13.14232  | 0.00154  | MXG_33  |

1 Ответ

0 голосов
/ 13 октября 2018

Метод .apply объекта groupby позволит вам предварительно обработать данные на уровне группы и вернуть фрейм данных.

def fn(group):
    group['weighted_avg'] = group['Price'] * group['Amount'] / group['Amount'].sum()
    return group

d_agg = {'Market':'first'
,'Type':'first'
,'weighted_avg':'sum'
,'Amount':'sum'
,'Total':'sum'
,'Fee':'sum'
,'Acc':'first'}

df.groupby('Time', sort=False).apply(fn).groupby('Time').agg(d_agg)

# if you don't understand what the code is doing, try:
print(df.groupby('Time', sort=False).apply(fn))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...