Определите, существует ли последовательность в Серии Панд, и верните строки, в которых эта последовательность найдена - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть следующий массив numpy, хранящийся как серия Панд.

array([0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0,
   0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1,
   0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
   0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1,
   1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1,
   0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1,
   1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
   1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0,
   1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
   0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1,
   0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0,
   1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
   0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0,
   1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,
   1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1,
   0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1,
   1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1,
   0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0,
   0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1,
   1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0,
   0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
   1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0,
   1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0,
   1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0,
   0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1,
   1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1,
   1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0,
   1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1,
   1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0,
   0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0,
   1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0,
   1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1,
   0, 1, 1, 0, 1, 1, 1])

Я хотел бы определить, есть ли в этом массиве определенная последовательность единиц.Если это так, я хотел бы получить строки.т.е. имеет ли этот массив последовательность из трех единиц?Где они?

Я пытался посмотреть в документации Pandas, например, isin () , но они имеют дело с определенным элементом, а не с последовательностью элементов.Кажется, не было никакой функции для удовлетворения моих потребностей.Я надеялся, что кто-нибудь сможет помочь.Спасибо.

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Это похоже на проблему , соответствующую шаблону .

Если вас интересует только поиск последовательностей из них, вот как вы можете реализовать простое решение, используя np.correlate.

Это работает вместо суммы абсолютных разностей, поскольку любая другая последовательность чисел приведет к значению корреляции <длина шаблона. </p>

import numpy as np
def find_matching_ones(sequence, length):
  correlated_values = np.correlate(sequence, np.ones((length)), "same")
  return np.where(correlated_values == length)[0] - length//2

def verify_results(sequence, length, indices):
  for idx in indices.tolist():
    reference = sequence[idx:(idx + length)]
    if not np.all(reference == 1):
      print(idx, reference)
      return False
  return True

for n in range(3, 7):
  indices = find_matching_ones(sequence, n)
  if verify_results(sequence, n, indices):
    print("Results matched for length ", n)
  else:
    print("Results did not match for length ", n)

Этот код предполагает, что ваш массив имеет имя sequence.

0 голосов
/ 18 декабря 2018

Решение Python

Вы можете использовать itertools.groupby, чтобы получить то, что вы хотите:

from itertools import groupby

def oneruns_groupby(arr, n):
    ix = 0
    ixs = []
    for k,g in groupby(arr):
        leng = len(list(g))
        if k and leng == n:
            ixs.append(ix)
        ix += leng
    return ixs

print(oneruns_groupby(arr, 3))

Так что если вы хотите найти индексы всех прогонов длины 3 (еслилюбой), вы бы использовали его так (я назову ваш массив arr, так как я не хочу копировать и вставлять всю огромную вещь):

oneruns_groupby(arr, 3)

Вывод:

[2, 17, 41, 71, 87, 100, 172, 265, 359, 376, 380, 410, 442, 495, 523, 551, 557, 609, 620, 627, 633, 637, 661, 710, 752]

Решение Numpy

Вот функция, которая даст вам стартовые индексы каждого прогона 1 значений заданной длины n:

def oneruns_npcomp(arr, n):
    d = np.diff(np.pad(arr, 1, 'constant'))
    start = (d > 0).nonzero()[0]
    runlen = (d < 0).nonzero()[0] - start

    return start[runlen == n]

Тестирование:

oneruns_npcomp(arr, 3)

Вывод:

array([  2,  17,  41,  71,  87, 100, 172, 265, 359, 376, 380, 410, 442,
       495, 523, 551, 557, 609, 620, 627, 633, 637, 661, 710, 752])

Быстрое и грязное решение

Вот альтернативное решение Numpy:

def oneruns_qd(arr, n):
    return ((np.diff(np.pad(arr, 1, 'constant'), n) == 0) & (arr[:-n] == 1)).nonzero()

Следует отметить, что быстрый и грязный метод находит все прогоны с 1 значениями длины 3 или более .

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