Поиск векторов внутри матрицы - PullRequest
0 голосов
/ 01 ноября 2019

Учитывая приведенную ниже матрицу ixs с индексами, я ищу вектор в ixs, который эквивалентен ix (также строка / вектор ixs), за исключением измерения1 (которое может принимать любое значение) и dimension3, который должен быть установлен на 1.

ixs = np.asarray([
 [0, 0, 3, 0, 1], # 0. current value of `ix`
 [0, 0, 3, 1, 1], # 1.
 [0, 1, 3, 0, 0], # 2.
 [0, 1, 3, 0, 1], # 3.
 [0, 1, 3, 1, 1], # 4.
 [0, 2, 3, 0, 1], # 5.
 [0, 2, 3, 1, 1]  # 6.
])
ix = np.asarray([0, 0, 3, 0, 1])

Так что с ix из [0, 0, 3, 0, 1] я бы посмотрел на все строки, которые ниже этой (строка 1 .. 6) и найдите шаблон [0, *, 3, 1, 1], т. Е. 1. [0, 0, 3, 1, 1], 4. [0, 1, 3, 1, 1], 6. [0, 2, 3, 1, 1].

Каков наилучший (краткий) способ получить эти векторы?

Ответы [ 2 ]

0 голосов
/ 01 ноября 2019

Вот простой для понимания подход с использованием cdist:

Мы используем взвешенное расстояние Хэмминга между ix и каждой строкой ixs. Это расстояние равно 0, если строки идентичны (мы используем это для двойной проверки того, что ix находится в ixs) и добавляет штраф за каждую разницу. Мы выбрали веса таким образом, чтобы разница в позиции 0,2 или 4 добавляла 3/11, а в позиции 1 или 3 - 1/11. Позже мы сохраняем только векторы с расстоянием <1/4, это позволяет векторам, которые отклоняются от ix на 1 или 3 или на оба, и блокировать все остальные. Затем мы проверяем отдельно на 1 в позиции 3. </p>

from scipy.spatial.distance import cdist

# compute distance note that weights are automatically normalized to sum 1
d = cdist([ix],ixs,"hamming",w=[3,1,3,1,3])[0]
# find ix
ixloc = d.argmin()
# make sure its exactly ix
assert d[ixloc] == 0

# filter out all rows that are different in col 0,2 or 4
hits, = ((d < 1/4) & (ixs[:,3] == 1)).nonzero()
# only keep hits below the row of ix:
hits = hits[hits.searchsorted(ixloc):]

hits
# array([1, 4, 6])
0 голосов
/ 01 ноября 2019

Это решение использует только NumPy (очень быстро) с несколькими логическими операциями. В конце он дает правильные столбцы.

ixs = np.matrix([
 [0, 0, 3, 0, 1], # 0. current value of `ix`
 [0, 0, 3, 1, 1], # 1.
 [0, 1, 3, 0, 0], # 2.
 [0, 1, 3, 0, 1], # 3.
 [0, 1, 3, 1, 1], # 4.
 [0, 2, 3, 0, 1], # 5.
 [0, 2, 3, 1, 1]  # 6.
])

newixs = ixs

#since the second column does not matter, we just assign it 0 in the new matrix.

newixs[:,1] = 0 

#here it compares the each row against the 0 indexed row
#then, it multiplies the True and False values with 1
#and the result is 0,1 values in an array. 
#then it takes the averages at the row level
#if the average is 1, then it means that all values match

mask = ((newixs == newixs[0])*1).mean(axis=1) == 1

#it then converts the matrix to array for masking
mask = np.squeeze(np.asarray(mask))

#using the mask value, we select the matched columns
ixs[mask,:]
matrix([[0, 0, 3, 0, 1],
        [0, 1, 3, 0, 1],
        [0, 2, 3, 0, 1]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...