Получить индекс минимального значения в строке в сочетании с другими ограничениями - PullRequest
2 голосов
/ 02 февраля 2020

Мне нужно найти индекс минимума на строку в 2-мерном массиве, который в то же время защищает дополнительное ограничение на значения столбца. Имея два массива a и b

a = np.array([[1,0,1],[0,0,1],[0,0,0],[1,1,1]])

b = np.array([[1,-1,2],[4,-1,1],[1,-1,2],[1,2,-1]])

, цель состоит в том, чтобы найти признаки, для которых установлено, что a == 1, b положительно, а b - минимальное значение строки , Выполнить первые два условия легко

idx = np.where(np.logical_and(a == 1, b > 0))

, что дает индексы:

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

Теперь мне нужно отфильтровать дублирующиеся записи строк (придерживаться только минимального значения), но я не могу думать элегантного способа достичь этого. В приведенном выше примере результат должен быть

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

edit :

Он также должен работать для a, содержащего другие значения, отличные от 0 и 1.

Ответы [ 2 ]

1 голос
/ 02 февраля 2020

Обновлено, чтобы попытаться лучше понять проблему, попробуйте:

c = b*(b*a > 0)
np.where(c==np.min(c[np.nonzero(c)]))

Вывод:

(array([0, 1, 3], dtype=int64), array([0, 2, 0], dtype=int64))

Время:

Метод 1

a = np.array([[1,0,1],[0,0,1],[0,0,0],[1,1,1]])
b = np.array([[1,-1,2],[4,-1,1],[1,-1,2],[1,2,-1]])
b[b<0] = 100000
cond = [[True if i == b.argmin(axis=1)[k] else False for i in range(b.shape[1])] for k in range(b.shape[0])]
idx = np.where(np.logical_and(np.logical_and(a == 1, b > 0),cond))
idx

Метод 2

c = b*(b*a > 0)
idx1 = np.where(c==np.min(c[np.nonzero(c)]))
idx1

Метод 1 Время:

28,3 мкс ± 418 нс на л oop ( среднее ± стандартное отклонение из 7 прогонов, 10000 циклов в каждом)

Метод 2 Время:

12,2 мкс ± 144 нс на л oop (среднее ± стандартное отклонение Dev из 7 прогонов, 100000 петель каждый)

0 голосов
/ 03 февраля 2020

Я нашел решение, основанное на понимании списка. Однако необходимо изменить отрицательные значения b на некоторое высокое значение.

a = np.array([[1,0,1],[0,0,1],[0,0,0],[1,1,1]])
b = np.array([[1,-1,2],[4,-1,1],[1,-1,2],[1,2,-1]])
b[b<0] = 100000
cond = [[True if i == b.argmin(axis=1)[k] else False for i in range(b.shape[1])] for k in range(b.shape[0])]
idx = np.where(np.logical_and(np.logical_and(a == 1, b > 0),cond))
print(idx)

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

Пожалуйста, дайте мне услышать, что вы думаете.

edit : Я только что заметил, что это решение ужасно медленное.

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