Поиск индексов для повторяющихся последовательностей в массиве NumPy - PullRequest
1 голос
/ 09 января 2020

Это продолжение до предыдущего вопроса . Если у меня есть NumPy массив [0, 1, 2, 2, 3, 4, 2, 2, 5, 5, 6, 5, 5, 2, 2] для каждой повторяющейся последовательности (начиная с каждого индекса), есть ли быстрый способ найти все совпадения этой повторяющейся последовательности и вернуть индекс для этих совпадений?

Здесь повторяющимися последовательностями являются [2, 2] и [5, 5] (обратите внимание, что длина повторения указывается пользователем, но будет такой же длины и может быть намного больше 2). Повторы можно найти в [2, 6, 8, 11, 13] следующим образом:

def consec_repeat_starts(a, n):
    N = n-1
    m = a[:-1]==a[1:]
    return np.flatnonzero(np.convolve(m,np.ones(N, dtype=int))==N)-N+1

Но для каждого уникального типа последовательности повтора (т. Е. [2, 2] и [5, 5]) я хочу вернуть что-то вроде повторения, за которым следуют индексы, где расположен повтор:

[([2, 2], [2, 6, 13]), ([5, 5], [8, 11])]

Обновление

Дополнительно, учитывая последовательность повторений, вы можете вернуть результаты из второго массива. Итак, ищите [2, 2] и [5, 5] in:

[2, 2, 5, 5, 1, 4, 9, 2, 5, 5, 0, 2, 2, 2]

И функция вернет:

[([2, 2], [0, 11, 12]), ([5, 5], [2, 8]))]

1 Ответ

0 голосов
/ 09 января 2020

Вот способ сделать это -

def group_consec(a, n):
    idx = consec_repeat_starts(a, n)
    b = a[idx]
    sidx = b.argsort()
    c = b[sidx]
    cut_idx = np.flatnonzero(np.r_[True, c[:-1]!=c[1:],True])
    idx_s = idx[sidx]
    indices = [idx_s[i:j] for (i,j) in zip(cut_idx[:-1],cut_idx[1:])]
    return c[cut_idx[:-1]], indices

# Perform lookup in another array, b
n = 2
v_a,indices_a = group_consec(a, n)
v_b,indices_b = group_consec(b, n)

idx = np.searchsorted(v_a, v_b)
idx[idx==len(v_a)] = 0
valid_mask = v_a[idx]==v_b
common_indices = [j for (i,j) in zip(valid_mask,indices_b) if i]
common_val = v_b[valid_mask]

Обратите внимание, что для простоты и удобства использования первый выходной аргумент group_consec имеет уникальные значения для каждой последовательности. Если они вам нужны в формате (val, val,..), просто скопируйте в конце. Аналогично для common_val.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...