Порог пороговых данных в зависимости от длины паттерна - PullRequest
1 голос
/ 06 марта 2019

У меня есть этот фрейм данных

    A
0   -2
1   0
2   2
3   2
4   0
5   0
6   0
7   0
8   0
9   0
10  0
11  0
12  2
13  2
14  2
15  2
16  2
17  3
18  2
19  0
20  2
21  2
22  2

и сюжет такой

enter image description here

Я хочу пороговые данные, основанные на длине последовательности для вышеприведенного примера, сглаживающей часть B, потому что ее длина меньше 3, как показано ниже

enter image description here

Ответы [ 2 ]

1 голос
/ 06 марта 2019

альтернативное решение без цикла for (с использованием df из ответа @ anand_v.singh):

  1. маска записей выше базовой линии (y = 0):
    positive_mask = df>0
  1. метка группы последовательных положительных значений:
    sequence_groups = positive_mask.astype(int).diff(1).fillna(0).abs().cumsum().squeeze()
  1. проверка размера каждой группы последовательностей
    sequence_size = positive_mask.groupby(sequence_groups).transform(len)
  1. собрать все вместе (только для просмотра данных и результатов шагов рядом)
    df_extended = pd.concat([df, positive_mask, sequence_groups, sequence_size], axis=1)
    df_extended.columns = ['value', 'is_positive', 'sequence_group', 'sequence_size']
    df_extended

        value  is_positive  sequence_group  sequence_size
    0      -2        False             0.0              2
    1       0        False             0.0              2
    2       2         True             1.0              2
    3       2         True             1.0              2
    4       0        False             2.0              8
    5       0        False             2.0              8
    6       0        False             2.0              8
    7       0        False             2.0              8
    8       0        False             2.0              8
    9       0        False             2.0              8
    10      0        False             2.0              8
    11      0        False             2.0              8
    12      2         True             3.0              7
    13      2         True             3.0              7
    14      2         True             3.0              7
    15      2         True             3.0              7
    16      2         True             3.0              7
    17      3         True             3.0              7
    18      2         True             3.0              7
    19      0        False             4.0              1
    20      2         True             5.0              3
    21      2         True             5.0              3
    22      2         True             5.0              3
    23      0        False             6.0              1
    24      3         True             7.0              2
    25      3         True             7.0              2
    26      0        False             8.0              1
  1. стирает все положительные значения, а размер последовательности меньше 3:
    flat_mask = (df_extended.sequence_size < 3) & (df_extended.is_positive)
    df_extended.loc[flat_mask, 'value'] = 0
  1. участок
    df_extended.value.plot()

enter image description here

1 голос
/ 06 марта 2019

Хорошо, так что сначала давайте создадим фрейм данных

df = pd.DataFrame([-2,0,2,2,0,0,0,0,0,0,0,0,2,2,2,2,2,3,2,0,2,2,2,0,3,3,0])
df.columns = ['A']
df

Я добавил два 3 и 4 в конце только для проверки работоспособности, это дает нам

    A
0   -2
1   0
2   2
3   2
4   0
5   0
6   0
7   0
8   0
9   0
10  0
11  0
12  2
13  2
14  2
15  2
16  2
17  3
18  2
19  0
20  2
21  2
22  2
23  0
24  3
25  3
26  0

Теперь мы должны увидеть, какие элементы должны быть обнулены для этого использования

prev = None
flag = 0
terminationLst = []
for val,i in zip(df['A'],df.index):
  if val == 0 and prev == None: #First time encountering a zero element
    prev = i 
    continue
  if val !=0 and prev != None: #Encountering a non zero element after having seen a zero
    flag = 1
  elif val == 0 and i-prev > 3: Encountering a zero after more than 3 consecutive none zeros
    prev = i
  elif val == 0 and i-prev <=3 and flag ==1: #Encountering a zero after less than 3 consecutive non zeros
    flag = 0
    terminationLst.append([x for x in range(prev+1,i)])
    prev = i
print (terminationLst)

, который дает нам индекс элементов, которые нам нужно повернуть в ноль [[2, 3], [24, 25], [27]]

Теперь нам просто нужно повернуть их в ноль, что можно сделать просто

for elem in terminationLst:
  df['A'].iloc[elem] = 0

А теперь датафрейм становится

    A
0   -2
1   0
2   0
3   0
4   0
5   0
6   0
7   0
8   0
9   0
10  0
11  0
12  2
13  2
14  2
15  2
16  2
17  3
18  2
19  0
20  2
21  2
22  2
23  0
24  0
25  0
26  0
27  0
28  0

Если у вас есть какие-либо проблемы с пониманием каких-либо конкретных частей, не стесняйтесь комментировать ниже.

...