Использование скользящего окна для точного определения последовательности в кадре данных с повторяющимися значениями (тот же заголовок и тот же хвост) - PullRequest
0 голосов
/ 10 ноября 2018

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

, т.е.: [z, x, y, n, z, z, x и т. Д.] [1,234, 2,4467, 2,999, 6,432, 9,6764 и т. Д.]

Я хочу обнаружить определенный шаблон (т. Е. Z, x, y, n, z) и создать новый столбец с информацией о том, является ли значение частью последовательности (называемое 'seq_bool'), с True или False для каждого значения). Который тогда выглядит так:

0    1    seq_bool
z  1.234  True
x  2.4467 True
y  2.999  True
n  6.432  True
z  9.6764 True
x  10.111 False
y  11.344 False
z  12.33  True
x  14.33  True
y  15.66  True
n  19.198 True
z  20.222 True
[...]

И затем я использую эту информацию, чтобы вычислить некоторые статистические данные в соответствующие моменты времени, по существу, принимая значения только часть последовательности.

У меня есть это уже через следующий код, из решения, уже найденного в stackoverflow

    def rolling_window(a, window):
    shape = a.shape[:-1] + (a.shape[-1] - window + 1, window)
    strides = a.strides + (a.strides[-1],)
    c = np.lib.stride_tricks.as_strided(a, shape=shape, strides=strides)
    return c
arr = new_df[0].values
b = np.all(rolling_window(arr, N) == sequence_pattern, axis=1)
c = np.mgrid[0:len(b)][b]

d = [i for x in c for i in range(x, x + N)]
new_df['seq_bool'] = np.in1d(np.arange(len(arr)), d)

Моя проблема в том, что не позволяет точно распознать последовательность, , потому что последовательность начинается и заканчивается одним и тем же символом (т. Е. 'Z')

В частности, если в моих данных есть следующие значения [z, x, y, n, z, x, y, n, z], функция распознает, что все эти значения являются частью последовательности (и являются «Правда»), когда на самом деле это не так. Существует только одна правильная последовательность (то есть [z, x, y, n, z]).

Я немного новичок в python, и я не знаю, как решить эту проблему. Есть ли способ указать, что при обнаружении последовательности вывести необходимую переменную, а затем отбросить ее и перейти к следующему значению в столбце? Чтобы не ошибочно принять хвост предыдущей правильной последовательности (то есть z) за начало новой последовательности.

Спасибо

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Мой подход будет рассматривать это как проблему find-substring. Посмотрите на это, если вам нравится:

word = ''.join(df['0'].values)
seq_bool = np.zeros(len(word)).astype(bool)
start = 0
while True:
    idx = word.find('zxynz', start)
    if idx < 0:
        break
    else:
        start = idx + 5
        seq_bool[idx:idx+5] =  True

df['seq_bool'] = seq_bool

EDIT:
Предполагается, что есть хотя бы один символ, о котором известно, что никогда не появится в df['0'], есть еще более короткий путь:

Допустим, T будет хорошо для работы индикатора:

word = ''.join(df['0'].values)
new_word = word.replace('zxynz', 'TTTTT')
df['seq_bool'] = np.array(list(new_word))=='T')
0 голосов
/ 10 ноября 2018

Опираясь на то, что у вас уже есть, перед его использованием вы можете удалить все значения в c, для которых расстояние до предыдущего значения меньше 5, убедившись, что удалили соответствующие значения, прежде чем двигаться дальше. То есть, если c = np.array([0, 7, 11, 15]), мы удалим 11, но оставим 15.

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

i = 0
while i < len(c)-1:
    if c[i+1] - c[i] < 5:
        c = np.delete(c, i+1)
    else:
        i += 1
...