Установите максимум строки в 1 и другие значения в 0 - PullRequest
0 голосов
/ 30 марта 2020

У меня есть матрица

x = array([[ 1,  2,  4,  6],
       [ 8, 29, 11, 35],
       [18, 16, 28, 25],
       [26, 28, 53, 52]])

Я хочу получить максимум и минимум вдоль строки и столбца и сделать его равным 1 и остальным 0. Я делаю следующим образом, чтобы получить максимум и минимум вдоль столбца:

getMax = np.where(x == np.amax(x, axis=0), 1, 0)
getMin = np.where(x == np.amin(x, axis=0), 1, 0)

после этого я получаю:

array([[0, 0, 0, 0],
       [0, 1, 0, 0],
       [0, 0, 0, 0],
       [1, 0, 1, 1]]) for maximum

и

array([[1, 1, 1, 1],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]]) for minimum

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

getMax = np.where(x == np.amax(x, axis=1), 1, 0)
getMin = np.where(x == np.amin(x, axis=1), 1, 0)

Я получаю это:

array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 1, 0],
       [0, 0, 0, 0]]) for maximum

и

array([[1, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]]) for minimum

что не так в коде для мин и макс вдоль строки?

1 Ответ

2 голосов
/ 30 марта 2020

Во втором случае сравниваемые оси не выровнены, необходимо убедиться, что размеры обоих массивов совпадают. Для этого у вас есть keepdims, который точно нацелен на сохранение формы ввода. Также нет необходимости в np.where, вы можете просто привести к int:

(x == np.max(x, axis=1, keepdims=True)).view('i1')

array([[0, 0, 0, 1],
       [0, 0, 0, 1],
       [0, 0, 1, 0],
       [0, 0, 1, 0]], dtype=int8)

Или мы могли бы использовать argmax с np.put_along_axis для более производительного подхода:

getMax = np.zeros_like(x)
np.put_along_axis(getMax,x.argmax(1)[:,None],1,axis=1)

Время:

a = np.concatenate([x]*10000, axis=0)

%timeit np.where(a == np.amax(a, axis=1, keepdims=True), 1, 0)
# 1.15 ms ± 6.64 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit (a == np.amax(a, axis=1, keepdims=True)).view('i1')
# 986 µs ± 13.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%%timeit
getMax = np.zeros_like(a)
np.put_along_axis(getMax,a.argmax(1)[:,None],1,axis=1)
# 436 µs ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Обратите внимание, что если вы не сохраните 2D-фигуру, вы получите:

np.amax(x, axis=1)
#array([ 6, 35, 28, 53])

, который является одномерным массивом, и будет сравнить по последней оси в x. Это становится понятным при сравнении размеров обоих массивов:

x.shape (2d array):                      4 x 4
np.amax(x, axis=1).shape (1d array):         4

В то время как вы действительно хотите:

x.shape (2d array):                          4 x 4
np.amax(x, axis=1, keepdims=True).shape:     4 x 1

, чтобы они сравнивались вдоль первой оси (ряды)

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