Панды: количество строк в прямом и обратном направлении при заданном значении сигнала - PullRequest
0 голосов
/ 02 января 2019

Есть ли способ эффективно подсчитать количество строк до и после определенного значения сигнала в Пандах?

Вот данные о Пандах. Вы можете увидеть столбец с именем « Сигнал », который имеет значения 0 и 1. Это данные. То, что я смотрю, это столбец " forwardBackwardRows ". В этом столбце вы видите, что для каждого значения сигнала 1 количество строк вперед и назад от этого значения. Я могу исправить это в цикле, но он не будет эффективным, поскольку в моих таблицах около 100 миллионов строк, а у меня около 1000 таких таблиц. Максимальное значение счетчика должно быть 2. Не более 2 строк должно быть подсчитано до или после сигнала

import pandas as pd
data = pd.DataFrame([[1420.49,0],[1421.12,0],[1418.95,0],[1419.04,1],[1419.04,0],[1417.51,0],[1416.97,0],[1413.21,0],[1411.49,1],[1412.57,0],[1408.55,0],[1411.56,0],[1409.16,0],[1413.38,0],[1413.38,1],[1402.35,0],[1413.22,0],[1411.7,0],[1397.8,0],[1398.36,0],[1397.62,0],[1394.58,1],[1399.05,0],[1399.9,0],[1398.96,1],[1398.96,0],[1393.69,0],[1398.13,0],[1398.66,1],[1398.02,0],[1397.97,1],[1396.05,0],[1398.13,1]], columns=["Values", "Signal"])

Вот изображение результата, за которым я присматриваю

+----+---------+--------+---------------------+
|    | Values  | Signal | forwardBackwardRows |
+----+---------+--------+---------------------+
|  0 | 1420.49 |      0 |                   0 |
|  1 | 1421.12 |      0 |                  -3 |
|  2 | 1418.95 |      0 |                  -2 |
|  3 | 1419.04 |      1 |                   1 |
|  4 | 1419.04 |      0 |                   2 |
|  5 | 1417.51 |      0 |                   3 |
|  6 | 1416.97 |      0 |                  -3 |
|  7 | 1413.21 |      0 |                  -2 |
|  8 | 1411.49 |      1 |                   1 |
|  9 | 1412.57 |      0 |                   2 |
| 10 | 1408.55 |      0 |                   3 |
| 11 | 1411.56 |      0 |                   0 |
| 12 | 1409.16 |      0 |                  -3 |
| 13 | 1413.38 |      0 |                  -2 |
| 14 | 1413.38 |      1 |                   1 |
| 15 | 1402.35 |      0 |                   2 |
| 16 | 1413.22 |      0 |                   3 |
| 17 |  1411.7 |      0 |                   0 |
| 18 |  1397.8 |      0 |                   0 |
| 19 | 1398.36 |      0 |                  -3 |
| 20 | 1397.62 |      0 |                  -2 |
| 21 | 1394.58 |      1 |                   1 |
| 22 | 1399.05 |      0 |                   2 |
| 23 |  1399.9 |      0 |                  -2 |
| 24 | 1398.96 |      1 |                   1 |
| 25 | 1398.96 |      0 |                   2 |
| 26 | 1393.69 |      0 |                   3 |
| 27 | 1398.13 |      0 |                  -2 |
| 28 | 1398.66 |      1 |                   1 |
| 29 | 1398.02 |      0 |                   2 |
| 30 | 1397.97 |      1 |                   1 |
| 31 | 1396.05 |      0 |                   2 |
| 32 | 1398.13 |      1 |                   1 |
+----+---------+--------+---------------------+

1 Ответ

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

Вот один из способов:

start = df[df.Signal == 1].iloc[0].name
end = df[df.Signal == 1].iloc[-1].name

Для увеличения счетчика вы можете сделать следующее:

g = df.Signal.cumsum()
pos = df.loc[start:, 'Signal'].groupby(g).cumcount()+1
pos = pos.reindex(index = df.index).fillna(0)
pos[pos > 3] = 0

А для уменьшения:

g2 = df.Signal[::-1].cumsum()[::-1]
neg = -(df.loc[:end, 'Signal'].groupby(g2).cumcount(ascending=False)+1) 
neg = neg.reindex(index = df.index).fillna(0)
neg[neg < -3] = 0

И вы можете использовать DataFrame.combine, чтобы получить ожидаемый результат:

def f(x,y):
    if x == 0.:
        return y
    if y == 0.:
        return x
    if abs(x) <= abs(y):
        return x
    else:
        return y

df['forwardBackwardRows'] = pos.combine(neg, func = f)

Выход:

     Values     Signal        forwardBackwardRows
0   1420.49       0                  0.0
1   1421.12       0                 -3.0
2   1418.95       0                 -2.0
3   1419.04       1                  1.0
4   1419.04       0                  2.0
5   1417.51       0                  3.0
6   1416.97       0                 -3.0
7   1413.21       0                 -2.0
8   1411.49       1                  1.0
9   1412.57       0                  2.0
10  1408.55       0                  3.0
11  1411.56       0                  0.0
12  1409.16       0                 -3.0
13  1413.38       0                 -2.0
14  1413.38       1                  1.0
15  1402.35       0                  2.0
16  1413.22       0                  3.0
17  1411.70       0                  0.0
18  1397.80       0                  0.0
19  1398.36       0                 -3.0
20  1397.62       0                 -2.0
21  1394.58       1                  1.0
22  1399.05       0                  2.0
23  1399.90       0                 -2.0
24  1398.96       1                  1.0
25  1398.96       0                  2.0
26  1393.69       0                  3.0
27  1398.13       0                 -2.0
28  1398.66       1                  1.0
29  1398.02       0                  2.0
30  1397.97       1                  1.0
31  1396.05       0                  2.0
32  1398.13       1                  1.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...