Выполнение простого вычисления min в Excel без использования цикла в фрейме данных

Эта проблема:

Итак, у меня есть, как я думал, очень простая формула Excel, которую я пытался воспроизвести во фрейме данных Python. Я пытаюсь воссоздать столбец PeriodDraw. Все, что нужно сделать, - это вычислить текущее значение, которое сообщает вам, насколько далеко вы получите максимальное значение pl, прежде чем вы сделаете новое значение max. Я пытаюсь найти способ вычислить этот столбец во фрейме данных без использования цикла или самым быстрым способом, если мне нужно пройти через него.

Ожидаемый результат: столбец PeriodDraw из приведенной ниже таблицы.


Что делают формулы:

Итак, общий PL - это промежуточный итог. Столбец max - это текущий максимум столбца Total PL, а Diff просто берет разницу между Total PL и столбцом Max.

В Excel формула, которая будет отображаться во второй строке розыгрыша периода, выглядит так: = IF (G2 = 0,0, MIN (G2, H1)), где G2 = Diff, а столбец H - это PeriodDraw.

По сути, если разница равна 0, это означает, что pl в настоящее время имеет максимальное значение. Если нет, то я хочу знать, меньше ли текущая разница, чем мое предыдущее значение? если да, то это новый мин, если не оставить прежним.


Вот ссылка на электронную таблицу, если вы хотите увидеть формулы: https://docs.google.com/spreadsheets/d/1lvwIi3ZwLU0Y_6G3fGHII_WvEPU8kPdJ9mUgHUVlBUc/edit?usp=sharing

Я смог повторить это только с помощью цикла for.

+------------+----------+---------+----------+----------+-------+--------+------------+
| TradeCount | Entry Px | Exit Px | Trade PL | Total PL |  Max  |  Diff  | PeriodDraw |
+------------+----------+---------+----------+----------+-------+--------+------------+
|          1 | 0.5057   | 0.6327  |    26656 |    26656 | 26656 |      0 |          0 |
|          2 | 0.66     | 0.6552  |    -1022 |    25634 | 26656 |  -1022 |      -1022 |
|          3 | 0.6577   | 0.6066  |   -10745 |    14889 | 26656 | -11767 |     -11767 |
|          4 | 0.6066   | 0.5682  |     8050 |    22939 | 26656 |  -3717 |     -11767 |
|          5 | 0.5682   | 0.5632  |    -1064 |    21875 | 26656 |  -4781 |     -11767 |
|          6 | 0.5632   | 0.5627  |       91 |    21966 | 26656 |  -4690 |     -11767 |
|          7 | 0.5627   | 0.5657  |      616 |    22582 | 26656 |  -4074 |     -11767 |
|          8 | 0.5876   | 0.5691  |    -3899 |    18683 | 26656 |  -7973 |     -11767 |
|          9 | 0.5527   | 0.5679  |     3178 |    21861 | 26656 |  -4795 |     -11767 |
|         10 | 0.5867   | 0.5777  |    -1904 |    19957 | 26656 |  -6699 |     -11767 |
|         11 | 0.5599   | 0.5597  |      -56 |    19901 | 26656 |  -6755 |     -11767 |
|         12 | 0.5875   | 0.5917  |      868 |    20769 | 26656 |  -5887 |     -11767 |
|         13 | 0.5757   | 0.5615  |    -2996 |    17773 | 26656 |  -8883 |     -11767 |
|         14 | 0.5752   | 0.5545  |    -4361 |    13412 | 26656 | -13244 |     -13244 |
|         15 | 0.5722   | 0.5827  |     2191 |    15603 | 26656 | -11053 |     -13244 |
|         16 | 0.5752   | 0.6528  |    16282 |    31885 | 31885 |      0 |          0 |
|         17 | 0.6511   | 0.6288  |    -4697 |    27188 | 31885 |  -4697 |      -4697 |
|         18 | 0.65     | 0.6487  |     -287 |    26901 | 31885 |  -4984 |      -4984 |
|         19 | 0.5919   | 0.6264  |    -7259 |    19642 | 31885 | -12243 |     -12243 |
|         20 | 0.6264   | 0.6323  |     1225 |    20867 | 31885 | -11018 |     -12243 |
|         21 | 0.6281   | 0.5617  |   -13958 |     6909 | 31885 | -24976 |     -24976 |
+------------+----------+---------+----------+----------+-------+--------+------------+

Что я пробовал до сих пор:

stats_df['Max'] = stats_df['PL_Accum'].cummax()
stats_df['Diff'] = stats_df['PL_Accum'] - stats_df['Max']
df = stats_df.copy().reset_index()
m = []
for i in df.index:
    if df.iloc[i, df.columns.get_loc('PL_Accum')] == df.iloc[i, df.columns.get_loc('Max')]:
        m.append(df.iloc[i, df.columns.get_loc('Diff')])
    elif i == 0:
        m.append(0)
    else:
        m.append(min(m[i - 1], df.iloc[i, df.columns.get_loc('Diff')]))

stats_df['PeriodDraw_Closed'] = m

@ScottBoston ожидаемый результат - столбец PeriodDraw в таблице выше. Я исправлю это, чтобы сделать это более понятным

novawaly 25.10.2018 18:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Давайте попробуем это, я включаю PD_close для сравнения: Думаю, вы ищите функцию cummin по группам.

df['PD_Close'] = df.groupby(df['Diff'].eq(0).cumsum())['Total PL']\
                   .transform(lambda x: x.cummin())-df['Max']

Подробности:

  • Мы разбиваем фрейм данных на группы, определяемые столбцом Diff, равным 0. Каким образом мы используем eq для установки строк, в которых diff равен нулю, а затем мы используем cumsum для увеличения счетчика каждый раз, когда Diff равен нулю.
  • Затем мы используем этот счетчик как способ сгруппировать фрейм данных на части. так что мы можем вычислить локальные минимумы. Используя cummin, мы можем сохранить текущий подсчет наименьшего значения, найденного в каждой группе для общего PL.
  • Наконец, мы вычитаем Макс из этого локального минимума в каждой группе.

Если вы запустите каждую маленькую часть этого утверждения, начиная с того, что находится внутри группы, а затем проработайте свою работу, вы увидите, что утверждение обретает форму.

Выход:

     TradeCount  Entry Px  Exit Px  Trade PL  Total PL    Max   Diff  PeriodDraw  PD_close
0             1    0.5057   0.6327     26656     26656  26656      0           0         0
1             2    0.6600   0.6552     -1022     25634  26656  -1022       -1022     -1022
2             3    0.6577   0.6066    -10745     14889  26656 -11767      -11767    -11767
3             4    0.6066   0.5682      8050     22939  26656  -3717      -11767    -11767
4             5    0.5682   0.5632     -1064     21875  26656  -4781      -11767    -11767
5             6    0.5632   0.5627        91     21966  26656  -4690      -11767    -11767
6             7    0.5627   0.5657       616     22582  26656  -4074      -11767    -11767
7             8    0.5876   0.5691     -3899     18683  26656  -7973      -11767    -11767
8             9    0.5527   0.5679      3178     21861  26656  -4795      -11767    -11767
9            10    0.5867   0.5777     -1904     19957  26656  -6699      -11767    -11767
10           11    0.5599   0.5597       -56     19901  26656  -6755      -11767    -11767
11           12    0.5875   0.5917       868     20769  26656  -5887      -11767    -11767
12           13    0.5757   0.5615     -2996     17773  26656  -8883      -11767    -11767
13           14    0.5752   0.5545     -4361     13412  26656 -13244      -13244    -13244
14           15    0.5722   0.5827      2191     15603  26656 -11053      -13244    -13244
15           16    0.5752   0.6528     16282     31885  31885      0           0         0
16           17    0.6511   0.6288     -4697     27188  31885  -4697       -4697     -4697
17           18    0.6500   0.6487      -287     26901  31885  -4984       -4984     -4984
18           19    0.5919   0.6264     -7259     19642  31885 -12243      -12243    -12243
19           20    0.6264   0.6323      1225     20867  31885 -11018      -12243    -12243
20           21    0.6281   0.5617    -13958      6909  31885 -24976      -24976    -24976
21           22    0.5589   0.6311    -15176     -8267  31885 -40152      -40152    -40152
22           23    0.6311   0.7148     17563      9296  31885 -22589      -40152    -40152
23           24    0.6925   0.6867      1204     10500  31885 -21385      -40152    -40152
24           25    0.6867   0.6874       133     10633  31885 -21252      -40152    -40152
25           26    0.6874   0.6260     12880     23513  31885  -8372      -40152    -40152
26           27    0.6260   0.7252     20818     44331  44331      0           0         0
27           28    0.7252   0.7177      1561     45892  45892      0           0         0
28           29    0.7092   0.7241      3115     49007  49007      0           0         0
29           30    0.7241   0.7303     -1316     47691  49007  -1316       -1316     -1316
..          ...       ...      ...       ...       ...    ...    ...         ...       ...
99          100    1.2640   1.2666      -560     43015  63273 -20258      -75040    -75040
100         101    1.2666   1.3050      8050     51065  63273 -12208      -75040    -75040
101         102    1.3222   1.3075     -3101     47964  63273 -15309      -75040    -75040
102         103    1.2927   1.3443    -10850     37114  63273 -26159      -75040    -75040
103         104    1.3458   1.3452      -140     36974  63273 -26299      -75040    -75040
104         105    1.3502   1.3484      -392     36582  63273 -26691      -75040    -75040
105         106    1.3578   1.4015      9163     45745  63273 -17528      -75040    -75040
106         107    1.4119   1.3982     -2891     42854  63273 -20419      -75040    -75040
107         108    1.4098   1.3950     -3122     39732  63273 -23541      -75040    -75040
108         109    1.3950   1.2162     37534     77266  77266      0           0         0
109         110    1.2236   1.2227       175     77441  77441      0           0         0
110         111    1.2317   1.2749     -9086     68355  77441  -9086       -9086     -9086
111         112    1.2749   1.3335     12292     80647  80647      0           0         0
112         113    1.3233   1.2642    -12425     68222  80647 -12425      -12425    -12425
113         114    1.2343   1.1587     15862     84084  84084      0           0         0
114         115    1.1655   1.1427      4774     88858  88858      0           0         0
115         116    1.1226   1.0950     -5810     83048  88858  -5810       -5810     -5810
116         117    1.0950   1.0927       469     83517  88858  -5341       -5810     -5810
117         118    1.0676   1.0243      9079     92596  92596      0           0         0
118         119    0.9734   1.0088     -7448     85148  92596  -7448       -7448     -7448
119         120    1.0327   1.0484      3283     88431  92596  -4165       -7448     -7448
120         121    1.0484   1.0769     -5999     82432  92596 -10164      -10164    -10164
121         122    1.0794   1.0766      -602     81830  92596 -10766      -10766    -10766
122         123    1.0766   1.0764        28     81858  92596 -10738      -10766    -10766
123         124    1.0794   1.0817       469     82327  92596 -10269      -10766    -10766
124         125    1.0817   1.0697      2506     84833  92596  -7763      -10766    -10766
125         126    1.0697   1.1097     -8414     76419  92596 -16177      -16177    -16177
126         127    1.1097   1.1247      3136     79555  92596 -13041      -16177    -16177
127         128    1.1462   1.1497       721     80276  92596 -12320      -16177    -16177
128         129    1.1497   1.1517      -434     79842  92596 -12754      -16177    -16177

Потрясающие! Это быстрее, чем использование цикла?

novawaly 25.10.2018 19:11

вау - это сбривает 0,3 секунды за запуск. большое спасибо! В образовательных целях не могли бы вы объяснить, что делает ваш код? Def оставит вам немного любви на linkedin

novawaly 25.10.2018 19:23

Это должно быть намного быстрее, чем цикл, потому что мы используем векторизованные операции на фрейме данных pandas. Вы пользуетесь преимуществом последовательного расположения в памяти, все вычисления выполняются за один проход.

Scott Boston 25.10.2018 20:40

Другие вопросы по теме