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

самый элегантный способ получить доступ к n-мерному массиву с (n-1) -мерным массивом по заданному измерению, как в фиктивном примере

a = np.random.random_sample((3,4,4))
b = np.random.random_sample((3,4,4))
idx = np.argmax(a, axis=0)

Как я могу получить доступ сейчас сidx a чтобы получить максимумы вa как будто я использовалa.max(axis=0)? или как получить значения, указанныеidx вb?

Я думал об использованииnp.meshgrid но я думаю, что это перебор. Обратите внимание, что размерaxis может быть любой полезной осью (0,1,2) и заранее неизвестна. Есть ли элегантный способ сделать это?

Ответы на вопрос(1)

Решение Вопроса

Использоватьadvanced-indexing -

m,n = a.shape[1:]
I,J = np.ogrid[:m,:n]
a_max_values = a[idx, I, J]
b_max_values = b[idx, I, J]

Для общего случая:

def argmax_to_max(arr, argmax, axis):
    """argmax_to_max(arr, arr.argmax(axis), axis) == arr.max(axis)"""
    new_shape = list(arr.shape)
    del new_shape[axis]

    grid = np.ogrid[tuple(map(slice, new_shape))]
    grid.insert(axis, argmax)

    return arr[tuple(grid)]

К сожалению, немного более неловко, чем такая естественная операция.

Для индексацииn dim массив с(n-1) dim массив, мы могли бы немного упростить его, чтобы дать нам сетку индексов для всех осей, например так -

def all_idx(idx, axis):
    grid = np.ogrid[tuple(map(slice, idx.shape))]
    grid.insert(axis, idx)
    return tuple(grid)

Следовательно, используйте его для индексации входных массивов -

axis = 0
a_max_values = a[all_idx(idx, axis=axis)]
b_max_values = b[all_idx(idx, axis=axis)]
 2006pmach07 сент. 2017 г., 20:49
Как я уже сказал, я не знаю заранее, чтоaxis 0 может быть любым другим значением. Это изменило бы порядок[idx, I, J] так что это не сработает. И это в основном идея, которую я упомянул с meshgrid ...
 unutbu07 сент. 2017 г., 22:04
all_idx действительно элегантно. Люблю твои посты, @Divakar!
 user235711207 сент. 2017 г., 23:52
Для справки, обратная совместимость обработки я имею в видуВот, Случай, когдаidx скаляр - это то, о чем я даже не задумывался, когда обработка обратной совместимости не сработала и был бы неверный результат, если бы мы сохранили список вместо кортежа. Как это показывает, поведение кортежа более последовательное и его легче прогнозировать.
 user235711207 сент. 2017 г., 22:24
all_idx это мило. Я не понимал, что использование формы вывода argmax вместо формы исходного массива упростит ситуацию. Что касается кортежа вместо списка, то расширенная семантика индексирования более понятна с помощью кортежа. Список в этом случае ведет себя одинаково из-за (не совсем правильно задокументированного) бита обратной совместимости, который преобразует список в кортеж при определенных условиях. Может быть удивительно, когда список обрабатывается как кортеж, а когда список индексируется как массив в индексировании NumPy, поэтому я предпочитаю создавать кортеж явно.
 Divakar07 сент. 2017 г., 22:22
@unutbu А теперь я вижу! Итак, если входa является одномерным массивом, то с помощью кортежа мы получили бы скаляр, который копирует.max() поведение. Но без кортежа мы получили бы массив с одним элементом. Так что, может быть, это одна из причин, по которой я считаю это кортежем.

Ваш ответ на вопрос