(Python) Отображение между двумя массивами с массивом приоритетов - PullRequest
0 голосов
/ 07 мая 2018

С учетом исходного массива

src = np.random.rand(320,240)

и индексный массив

idx = np.indices(src.shape).reshape(2, -1)
np.random.shuffle(idx.T)

мы можем сопоставить линейный индекс i в src с двумерным индексом idx[:,i] в массиве назначения dst через

dst = np.empty_like(src)
dst[tuple(idx)] = src.ravel()

Это обсуждается в Python: отображение между двумя массивами с индексным массивом

Однако, если это отображение не 1-к-1, т. Е. Несколько записей в src отображаются на одну и ту же запись в dst, в соответствии с документами , то не указано, какой из исходные записи будут записаны в dst:

Для расширенных назначений, как правило, нет гарантии для порядка итерации. Это означает, что если элемент задан более одного раза, невозможно предсказать окончательный результат.

Если нам дополнительно дан массив приоритетов

p = np.random.rand(*src.shape)

как мы можем использовать p для устранения этой ситуации, то есть написать запись с наивысшим приоритетом в соответствии с p?

1 Ответ

0 голосов
/ 07 мая 2018

Вот метод, использующий разреженную матрицу для сортировки (он имеет большие накладные расходы, но масштабируется лучше, чем argsort, предположительно, потому что он использует некоторый метод сортировки по радиусу, подобный методу (?)). Дублирующиеся индексы без приоритета явно устанавливаются в -1. Мы делаем массив назначения на одну ячейку слишком большим, избыточная ячейка служит мусорным баком.

import numpy as np
from scipy import sparse

N = 2
idx = np.random.randint(0, N, (2, N, N))
prec = np.random.random((N, N))
src = np.arange(N*N).reshape(N, N)

def f_sparse(idx, prec, src):
    idx = np.ravel_multi_index(idx, src.shape).ravel()
    sp = sparse.csr_matrix((prec.ravel(), idx, np.arange(idx.size+1)),
                           (idx.size, idx.size)).tocsc()
    top = sp.indptr.argmax()
    mx = np.repeat(np.maximum.reduceat(sp.data, sp.indptr[:top]),
                   np.diff(sp.indptr[:top+1]))
    res = idx.copy()
    res[sp.indices[sp.data != mx]] = -1

    dst = np.full((idx.size + 1,), np.nan)
    dst[res] = src.ravel()
    return dst[:-1].reshape(src.shape)

print(idx)
print(prec)
print(src)
print(f_sparse(idx, prec, src))

Пример прогона:

[[[1 0]
  [1 0]]

 [[0 1]
  [0 0]]]
[[0.90995366 0.92095225]
 [0.60997092 0.84092015]]
[[0 1]
 [2 3]]
[[ 3.  1.]
 [ 0. nan]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...