Как проверить, присутствует ли один Pandas временной ряд в другом длинном временном ряду? - PullRequest
0 голосов
/ 09 марта 2020

У меня есть два очень длинных временных ряда. Я должен проверить, присутствует ли серия B (в указанном порядке) в серии A.

Серия A: 1,2,3,4,5,6,5,4,3. Серия B: 3,4,5.

Результат: True, с индексом, в котором найден первый элемент небольшой серии. Здесь, индекс: 2 (так как 3 присутствует в индексе 2 в Серии А)

Примечание: эти две серии довольно большие. скажем, A содержит 50000 элементов, а B содержит 350.

Ответы [ 3 ]

0 голосов
/ 10 марта 2020

Наивным подходом является проверка на B (1) в A. В вашем примере B (1) = A (3), так что теперь вы должны проверить, если B (2) = A (4), и вы продолжаете до конец вашей подстроки ... Если это не правильно, начните с A (4) и продолжайте до конца.

Лучший способ поиска подстроки - применить алгоритм Кнута-Морриса-Пратта. Я дам вам поиск дополнительной информации об этом!

0 голосов
/ 10 марта 2020

К сожалению, метод rolling для pandas не позволяет использовать его в качестве итератора, даже если реализация запланирована в # 11704 .
Таким образом, мы должны реализовать скользящее окно для подмножества проверяем сами.

ser_a = pd.Series(data=[1, 2, 3, 4, 5, 6, 5, 4, 3])
ser_b = pd.Series(data=[3, 4, 5])

slider_df = pd.concat(
    [ser_a.shift(-i)[:ser_b.size] for i in range(ser_a.size - ser_b.size + 1)], 
    axis=1).astype(ser_a.dtype).T
sub_series = (ser_b == slider_df).all(axis=1)
# if you want, you can extract only the indices where a subseries was found:
sub_series_startindex = sub_series.index[sub_series]

Что я здесь делаю:

  • [ser_a.shift(-i)[:ser_b.size] for i in range(ser_a.size - ser_b.size + 1)]: создать «скользящее окно» путем увеличения смещения ser_a, ограниченного размер подсерии ser_b для проверки. Поскольку сдвиги в конце будут давать NaN, они исключаются в range.
  • pd.concat(..., axis=1): объединить сдвинутые ряды, так что slider_df содержит все сдвиги в столбцах.
  • .astype(ser_a.dtype): строго необязательно. Для больших серий это может повысить производительность, для малых серий - ухудшить производительность.
  • .T: транспонировать df, чтобы индекс подсерии совпадал по оси 0.
  • sub_series = (ser_b == slider_df).all(axis=1): Найти, где ser_b соответствует подсерии.
  • sub_series.index[sub_series]: извлечь индексы, где была найдена соответствующая подсерия.
0 голосов
/ 09 марта 2020

очень медленное решение - преобразовать серию в список и проверить, является ли первый список подмножеством основного списка в следующем порядке:

def is_series_a_subseries_in_order(main, sub):
    n = len(sub)
    main=main.tolist()
    sub=sub.tolist()
    return any((main[i:i+n] == sub) for i in range(len(main)-n+1))

вернет True или False

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