#python #pandas #pandas-groupby
#python #pandas #pandas-groupby
Вопрос:
Как я могу выполнить скользящую сумму столбца Trade_Cost
, когда столбец Buy(C)/Sell(V)
находится C
, и сбрасывать эту сумму каждый раз Current_Qntd
при попадании 0
, а затем запускать новую скользящую сумму до следующего zero
?
Buy(C)/Sell(V) Qntd Price Current_Qntd Trade_Cost
0 C 33000 103.980000 33000 3.431340e 06
1 C 3682 102.940000 36682 3.790251e 05
2 C 108 103.490000 36790 1.117692e 04
3 C 10717 103.500000 47507 1.109210e 06
4 C 6831 103.760000 54338 7.087846e 05
5 C 968 107.000000 55306 1.035760e 05
6 C 32 107.000000 55338 3.424000e 03
7 V 3644 115.618296 51694 4.213131e 05
8 V 4704 115.995689 46990 5.456437e 05
9 V 46990 116.030000 0 5.452250e 06
10 C 35000 116.000000 35000 4.060000e 06
11 C 16000 117.999073 51000 1.887985e 05
12 V 1200 115.274742 49800 1.383297e 05
13 V 1400 116.700036 48400 1.633800e 05
14 V 23855 116.406567 24545 2.776879e 06
15 V 2589 116.247625 21956 3.009651e 05
16 V 12741 115.952801 9215 1.477355e 06
17 V 9132 115.951078 83 1.058865e 06
18 V 83 115.950000 0 9.623850e 03
Редактировать:
Я получил ответ ниже из другого вопроса, который я разместил здесь, в StackOverflow, но он не соответствует моим потребностям, потому что у меня много ресурсов в этом df, а приведенный выше пример предназначен только для одного ресурса.
grp = (df['Current_Qntd'] == 0).cumsum()
df['Trade_Cost Sum'] = df['Trade_Cost'].mask(df['Buy(C)/Sell(V)'] != 'C', 0)
df['Trade_Cost Sum'] = df.groupby(grp)['Trade_Cost Sum'].cumsum()
Приведенный выше ответ отлично работает для DF только с одним активом, но мне нужно было бы сгруппировать по активу в DF со многими активами. Ниже приводится продолжение вышеупомянутого DF, но с двумя активами
Buy(C)/Sell(V) Qntd Price Current_Qntd Trade_Cost Asset
0 C 100 114.290000 100 11429.000000 2
1 C 3137 115.020000 3237 360817.740000 2
2 V 100 114.500000 3137 11450.000000 2
3 V 1200 114.670000 1937 137604.000000 2
4 V 1937 115.000000 0 222755.000000 2
5 C 5586 96.790000 5586 540668.940000 2
6 V 5586 116.590000 0 651271.740000 2
7 C 971 118.630000 971 115189.730000 2
8 V 971 129.800000 0 126035.800000 2
9 C 600 126.416417 600 75849.850002 2
10 C 33000 103.980000 33000 3.431340e 06 1
11 C 3682 102.940000 36682 3.790251e 05 1
12 C 108 103.490000 36790 1.117692e 04 1
13 C 10717 103.500000 47507 1.109210e 06 1
14 C 6831 103.760000 54338 7.087846e 05 1
15 C 968 107.000000 55306 1.035760e 05 1
16 C 32 107.000000 55338 3.424000e 03 1
17 V 3644 115.618296 51694 4.213131e 05 1
18 V 4704 115.995689 46990 5.456437e 05 1
19 V 46990 116.030000 0 5.452250e 06 1
20 C 35000 116.000000 35000 4.060000e 06 1
21 C 16000 117.999073 51000 1.887985e 06 1
22 V 1200 115.274742 49800 1.383297e 05 1
23 V 1400 116.700036 48400 1.633800e 05 1
24 V 23855 116.406567 24545 2.776879e 06 1
25 V 2589 116.247625 21956 3.009651e 05 1
26 V 12741 115.952801 9215 1.477355e 06 1
27 V 9132 115.951078 83 1.058865e 06 1
28 V 83 115.950000 0 9.623850e 03 1
ПРАВКА 2:
grp = (df['Current_Qntd'] == 0).cumsum()
группирует ли 2 разных ресурса с помощью current_qntd = 0, как я могу сгруппировать его по активу?
Комментарии:
1. Добавьте ‘Asset’ вместе с
grp
:df.groupby(['Asset', grp])...
2. Ваш вопрос звучит сложнее, чем есть на самом деле.
Current_Qntd
переходит в 0 всякий раз, когда у группы естьBuy(C)/Sell(V)
==V
, поэтому просто определите свой groupby() по некоторому списку столбцов.3. Я добавил ресурс в groupby, как сказал @QuangHoang, но он неправильно выполняет cumsum после того, как Current_Qntd достигнет нуля
4. @smci Я считаю, что есть проблема
grp = (df['Current_Qntd'] == 0).cumsum()
, потому что, когда я добавляю его в качестве столбца и фильтрую столбец по grp, я вижу разные активы с одинаковым номером grp5. Тогда вы должны
groupby(['Asset', grp], ...)
, как сказал QuangHoang. Когда вы говорите «но он неправильно выполняет cumsum после того, как Current_Qntd достигнет нуля» , пожалуйста, покажите вывод и точно объясните, почему это неправильно.
Ответ №1:
Затем вы просто группируете по только что созданному столбцу и активу, нет?
grp = (df['Current_Qntd'] == 0).cumsum()
df['Trade_Cost Sum'] = df['Trade_Cost'].mask(df['Buy(C)/Sell(V)'] != 'C', 0)
df['Trade_Cost Sum'] = df.groupby(["Asset", grp])['Trade_Cost Sum'].cumsum()
Создает это:
Buy(C)/Sell(V) Qntd Price ... Trade_Cost Asset Trade_Cost Sum
0 C 100 114.290000 ... 1.142900e 04 2 1.142900e 04
1 C 3137 115.020000 ... 3.608177e 05 2 3.722467e 05
2 V 100 114.500000 ... 1.145000e 04 2 3.722467e 05
3 V 1200 114.670000 ... 1.376040e 05 2 3.722467e 05
4 V 1937 115.000000 ... 2.227550e 05 2 0.000000e 00
5 C 5586 96.790000 ... 5.406689e 05 2 5.406689e 05
6 V 5586 116.590000 ... 6.512717e 05 2 0.000000e 00
7 C 971 118.630000 ... 1.151897e 05 2 1.151897e 05
8 V 971 129.800000 ... 1.260358e 05 2 0.000000e 00
9 C 600 126.416417 ... 7.584985e 04 2 7.584985e 04
10 C 33000 103.980000 ... 3.431340e 06 1 3.431340e 06
11 C 3682 102.940000 ... 3.790251e 05 1 3.810365e 06
12 C 108 103.490000 ... 1.117692e 04 1 3.821542e 06
13 C 10717 103.500000 ... 1.109210e 06 1 4.930752e 06
14 C 6831 103.760000 ... 7.087846e 05 1 5.639537e 06
15 C 968 107.000000 ... 1.035760e 05 1 5.743113e 06
16 C 32 107.000000 ... 3.424000e 03 1 5.746537e 06
17 V 3644 115.618296 ... 4.213131e 05 1 5.746537e 06
18 V 4704 115.995689 ... 5.456437e 05 1 5.746537e 06
19 V 46990 116.030000 ... 5.452250e 06 1 0.000000e 00
20 C 35000 116.000000 ... 4.060000e 06 1 4.060000e 06
21 C 16000 117.999073 ... 1.887985e 06 1 5.947985e 06
22 V 1200 115.274742 ... 1.383297e 05 1 5.947985e 06
23 V 1400 116.700036 ... 1.633800e 05 1 5.947985e 06
24 V 23855 116.406567 ... 2.776879e 06 1 5.947985e 06
25 V 2589 116.247625 ... 3.009651e 05 1 5.947985e 06
26 V 12741 115.952801 ... 1.477355e 06 1 5.947985e 06
27 V 9132 115.951078 ... 1.058865e 06 1 5.947985e 06
28 V 83 115.950000 ... 9.623850e 03 1 0.000000e 00
Обратите внимание, что сумма торговых затрат в строке 10 совпадает с суммой торговых затрат для этой строки, поэтому совокупная сумма сбрасывается правильно.
Комментарии:
1. Я считаю, что есть проблема
grp = (df['Current_Qntd'] == 0).cumsum()
, потому что, когда я добавляю его в качестве столбца и фильтрую столбец по grp, я вижу разные активы с одинаковым номером grp