python numpy argmax до максимума в многомерном массиве

У меня есть следующий код:

import numpy as np
sample = np.random.random((10,10,3))
argmax_indices = np.argmax(sample, axis=2)

то есть я беру argmax вдоль оси = 2, и это дает мне матрицу (10,10). Теперь я хочу присвоить этим индексам значение 0. Для этого я хочу проиндексировать массив образцов. Я старался:

max_values = sample[argmax_indices]

но это не работает. я хочу что-то вроде

max_values = sample[argmax_indices]
sample[argmax_indices] = 0

Я просто подтверждаю, проверяя, что max_values - np.max(sample, axis=2) должен давать нулевую матрицу формы (10,10). Любая помощь будет оценена.


person Rayyan Riaz    schedule 28.02.2017    source источник
comment
Почему так? Значение матрицы при максимизации показателей по плоскости/оси должно быть равно максимальному значению матрицы по этой плоскости. Нет? Или numpy принимает максимум по всем значениям оси = 2 независимо от того, что такое 1-я и 2-я оси?   -  person Rayyan Riaz    schedule 01.03.2017
comment
Позвольте мне спросить это по-другому. Мой массив 10x10x3. Итак, для каждого i (ось x) и j (ось y) я хочу лучший k (ось z). Мне нужен его индекс, а также значение. Вышеупомянутый подход не подходит для этого?   -  person Rayyan Riaz    schedule 01.03.2017
comment
Извините, я не понимаю, но похоже, что ваша индексация все равно неверна, посмотрите ответы.   -  person Stop harming Monica    schedule 01.03.2017


Ответы (3)


Вот один подход -

m,n = sample.shape[:2]
I,J = np.ogrid[:m,:n]
max_values = sample[I,J, argmax_indices]
sample[I,J, argmax_indices] = 0

Пример пошагового запуска

1) Пример входного массива:

In [261]: a = np.random.randint(0,9,(2,2,3))

In [262]: a
Out[262]: 
array([[[8, 4, 6],
        [7, 6, 2]],

       [[1, 8, 1],
        [4, 6, 4]]])

2) Получите индексы argmax по axis=2 :

In [263]: idx = a.argmax(axis=2)

3) Получите форму и массивы для индексации в первые два размера:

In [264]: m,n = a.shape[:2]

In [265]: I,J = np.ogrid[:m,:n]

4) Индекс с использованием I, J и idx для хранения максимальных значений с использованием advanced-indexing :

In [267]: max_values = a[I,J,idx]

In [268]: max_values
Out[268]: 
array([[8, 7],
       [8, 6]])

5) Убедитесь, что мы получаем массив all zeros после вычитания np.max(a,axis=2) из max_values:

In [306]: max_values - np.max(a, axis=2)
Out[306]: 
array([[0, 0],
       [0, 0]])

6) Снова с помощью advanced-indexing назначьте эти места как zeros и выполните еще один уровень визуальной проверки:

In [269]: a[I,J,idx] = 0

In [270]: a
Out[270]: 
array([[[0, 4, 6], # <=== Compare this against the original version
        [0, 6, 2]],

       [[1, 0, 1],
        [4, 0, 4]]])
person Divakar    schedule 28.02.2017
comment
Большое спасибо :) Это идеально - person Rayyan Riaz; 01.03.2017

Альтернативой np.ogrid является np.indices.

I, J = np.indices(argmax_indices.shape)

sample[I,J,argmax_indices] = 0

person TianLe Ma    schedule 17.06.2017

Это также может быть обобщено для обработки матриц любой размерности. Полученная функция установит наибольшее значение в каждом одномерном векторе матрицы по любому желаемому измерению d (размерность 2 в случае исходного вопроса) равным 0 (или любому желаемому значению):

def set_zero(sample, d, val):
    """Set all max value along dimension d in matrix sample to value val."""
    argmax_idxs = sample.argmax(d)
    idxs = [np.indices(argmax_idxs.shape)[j].flatten() for j in range(len(argmax_idxs.shape))]
    idxs.insert(d, argmax_idxs.flatten())
    sample[idxs] = val
    return sample

set_zero(sample, d=2, val=0)

(Проверено для numpy 1.14.1 на python 3.6.4 и python 2.7.14)

person 0range    schedule 07.03.2018