Как искать в массиве numpy субвектор? - PullRequest
2 голосов
/ 19 апреля 2020


У меня есть массив numpy (в Python 3), и я хотел бы найти в нем подвектор.
Если я ищу полный вектор, этот код работает:

import numpy as np

a = np.zeros([10,5])
a[0] = [5,6,4,8,5]
a[1] = [3,6,8,5,3]
a[2] = [3,2,1,5,3]
a[3] = [6,5,6,4,6]
a[4] = [3,4,7,6,3]
a[5] = [2,3,1,5,2]
a[6] = [1,1,3,2,1]
a[7] = [6,5,8,8,6]
a[8] = [5,4,9,7,5]
a[9] = [1,2,7,8,1]

print(a)
search = [2,3,1,5,2] # correctly returns 5
i = np.argwhere(np.all((a-np.array(search))==0, axis=1))
print(int(i))

Хорошо, но я бы хотел найти этот подвектор:

search = [2,3,1,5]

Как мне его найти?

Ответы [ 3 ]

0 голосов
/ 19 апреля 2020
import numpy as np

a = np.zeros([10, 5])
a[0] = [5, 6, 4, 8, 5]
a[1] = [3, 6, 8, 5, 3]
a[2] = [3, 2, 1, 5, 3]
a[3] = [6, 5, 6, 4, 6]
a[4] = [3, 4, 7, 6, 3]
a[5] = [2, 3, 1, 5, 2]
a[6] = [1, 1, 3, 2, 1]
a[7] = [6, 5, 8, 8, 6]
a[8] = [5, 4, 9, 7, 5]
a[9] = [1, 2, 7, 8, 1]

search = [2, 3, 1, 5]
for i, row in enumerate(a):
    strided_row = np.lib.stride_tricks.as_strided(
        row, (a.shape[1] - len(search) + 1, len(search)), (a.itemsize, a.itemsize)
    )
    if (strided_row == search).all(axis=1).any():
        break
else:
    i = None
print(i)

Предполагая, что search является непрерывной частью некоторого ряда a. Документация для as_strided () . Например, для первой строки: strided_row равно [[5, 6, 4, 8], [6, 4, 8, 5]], тогда мы можем искать search так же, как и в вопросе.

0 голосов
/ 19 апреля 2020

Простое numpy решение:

Поиск в массиве raveled и остановка при первом появлении (вы сможете изменить его для любого типа поиска, который вы считаете подходящим, в том числе, если ваш список search охватывает несколько строки И также находя множественные вхождения search в a).

В следующем коде предполагается, что вы ищете первое вхождение в строке a:

for i in range(a.size-len(search)):
    if np.array_equal(np.ravel(a)[i:i+len(search)], np.array(search)) and int(i/a.shape[1])==int((i+len(search)-1)/a.shape[1]):
        print(int(i/a.shape[1]))
        break

Если скорость имеет значение, а a / search велико, сохраните раскованную версию из a в a_ravel = np.ravel(a) и numpy массив np.array(search) и использовать его внутри для l oop.

0 голосов
/ 19 апреля 2020

Это один из способов,

РЕДАКТИРОВАТЬ : в следующем коде предполагается, что ваш search вектор начинается в начале строки

import numpy as np

a = np.zeros([10,5])
a[0] = [5,6,4,8,5]
a[1] = [3,6,8,5,3]
a[2] = [3,2,1,5,3]
a[3] = [6,5,6,4,6]
a[4] = [3,4,7,6,3]
a[5] = [2,3,1,5,2]
a[6] = [1,1,3,2,1]
a[7] = [6,5,8,8,6]
a[8] = [5,4,9,7,5]
a[9] = [1,2,7,8,1]
search = [2,3,1,5]

s = search+[None]*((a.shape[1]-len(search)))
loc = np.where((a==s).sum(1)== len(search))

Выход

loc 
(array([5], dtype=int64),)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...