По сравнению с axis = 0, как np.argmin(arr, axis = 1) работает с 2D и 3D массивами?

#python #arrays #numpy

#python #массивы #numpy

Вопрос:

Я знаю, как это np.argmin(arr, axis=0) работает. Но np.argmin(arr, axis=1) меня смутил.

Пример 1:

Код:

 a2 = np.array([[1. , 2. , 3.3],
               [4. , 5. , 6.5]])

np.argmin(a2, axis=1)
  

Вывод:

 array([0, 0], dtype=int64)
  

Путаница:

Меня смущает то, что всего есть 2 индекса и 3 столбца. Тогда почему он выдает результат (0,0)? Вместо этого он должен выдавать следующие результаты:

Ожидаемый результат # 1:

 array([0], dtype=int64)
  

Причина:
Потому что он нашел самый низкий элемент в «индексе 0».

Ожидаемый результат # 2:

 array([0, 0, 0], dtype=int64)
  

Причина:
Потому что после сравнения элементов с индексом 0 элементов с индексом 1. Следует сказать, что каждый раз, когда я проводил сравнение с обоими индексами, я находил наименьший элемент в индексе 0

Пример 2:

Код:

 a5 = np.array([[[ 1,  2,  3,  4],
                [ 4,  5,  6,  7],
                [ 7,  8,  9, 10]],

               [[10, 11, 12, 13],
                [16, 17, 18, 19],
                [19, 20, 21, 22]]])

np.argmin(a5, axis=1)
  

Вывод:

 array([[0, 0, 0, 0],
       [0, 0, 0, 0]], dtype=int64)
  

Путаница:
Теперь, почему он выдает мне 4 столбца и 2 строки в выходных данных?

Комментарии:

1. Это не тот результат, который вы получаете, результат array([0, 0, 0], dtype=int64) — вы, вероятно, допустили опечатку и перешли к SO перед двойной проверкой? Или это опечатка в вашем вопросе, и вы спрашиваете о np.argmin(a2, axis=1) вместо этого? axis = 0 перебирает строки, получается три результата, по одному для каждого столбца. axis = 1 в 2D массиве все наоборот.

2. Нет ничего лучше документации, если вы в замешательстве. В нем говорится np.argmin , что возвращает индексы минимальных значений вдоль оси. И axis=1 — это столбцы. Ну, минимальные значения равны 1 и 4, оба имеют нулевые индексы, поэтому результат [0, 0] . Я думаю, вы должны быть очень осторожны, пытаясь понять эти описательные предложения в документах numpy.

3. Да, я дважды проверил свой код и все остальное. Результат, который я получаю, такой же, как в моем вопросе. Фактически, позвольте мне обновить мой вопрос другим примером другого массива, который делает то же самое.

4. @mathfux ты всегда рядом, чтобы спасти меня, чувак. Позвольте мне дополнить мой вопрос другим примером, чтобы вы могли лучше понять, что меня смущает.

5. @mathfux Я обновил свой вопрос с помощью примера 1 и примера 2.

Ответ №1:

Обработка np.min и argmin одинакова, независимо от номера оси. 0 не означает ничего более особенного, чем 1 или 2. Во всех случаях именованная ось удаляется из результата (то же самое для np.sum ).

Давайте сделаем что-то более случайное и более интересное:

 In [216]: arr = np.arange(24)
In [218]: np.random.shuffle(arr)
In [219]: arr
Out[219]: 
array([10,  2, 12, 11, 15,  8, 17, 20, 13, 21, 14,  1, 22,  7,  3,  5,  9,
        0, 19, 16, 18,  6, 23,  4])
In [220]: arr = arr.reshape(2,3,4)
In [221]: arr
Out[221]: 
array([[[10,  2, 12, 11],
        [15,  8, 17, 20],
        [13, 21, 14,  1]],

       [[22,  7,  3,  5],
        [ 9,  0, 19, 16],
        [18,  6, 23,  4]]])
  

С помощью axis=0 определите, какая ‘плоскость’ имеет минимальное значение для каждого элемента ‘row / col’.

 In [222]: np.min(arr, axis=0)
Out[222]: 
array([[10,  2,  3,  5],
       [ 9,  0, 17, 16],
       [13,  6, 14,  1]])
In [223]: np.argmin(arr, axis=0)
Out[223]: 
array([[0, 0, 1, 1],
       [1, 1, 0, 1],
       [0, 1, 0, 0]])
  

argmin значения — это значения индекса значений для измерения размера 2. 10 Находится в первой плоскости, 3 во второй и так далее.

Делаем то же самое с axis 2 (строки):

 In [224]: np.min(arr, axis=2)
Out[224]: 
array([[2, 8, 1],
       [3, 0, 4]])
In [225]: np.argmin(arr, axis=2)
Out[225]: 
array([[1, 1, 3],
       [2, 1, 3]])
  

2 Находится во втором столбце, 1 в четвертом и т.д.

Использование этого argmin для извлечения min значений требует некоторого знакомства с расширенной индексацией:

 In [226]: arr[[[0],[1]], [0,1,2], _225]     # Out[225] argmin
Out[226]: 
array([[2, 8, 1],
       [3, 0, 4]])
  

Здесь я использую массивы (2,1) и (3,) (или списки, которые могут быть преобразованы в массивы), которые будут транслироваться вместе, чтобы соответствовать индексу (2,3) argmin . Вместе они выбирают (2,3) массив значений из (2,3,4) сформированного arr .

Предполагается, что новая функция take_along_axis упростит применение argmin . У него есть пример. Применяется здесь:

 In [236]: idx = _225    
In [237]: np.take_along_axis(arr, idx[...,None], axis=2)
Out[237]: 
array([[[2],
        [8],
        [1]],

       [[3],
        [0],
        [4]]])
  

Это Out[224] np.min массив, расширенный до 3d (2,3,1) формы. Может быть проще выбрать минимальные элементы на Out[221] дисплее.

 In [238]: idx[...,None]
Out[238]: 
array([[[1],
        [1],
        [3]],

       [[2],
        [1],
        [3]]])
  

Комментарии:

1. большое вам спасибо за ваше драгоценное время. Я действительно ценю это. Ваше объяснение было очень полезным для меня при создании моих заметок. Я бы сохранил это так же удобно, как ссылку 🙂

Ответ №2:

Похоже, что я также не могу получить эти обозначения полностью, потому что я всегда ловлю себя на том, что путаю последнюю ось с предпоследней:

2D модель (строка-столбец)

введите описание изображения здесь

К сожалению, результаты np.argmin для разных осей являются:

 np.argmin(arr, axis=0)    np.argmin(arr, axis=1) 
       [0 0 1]                    [0 2]
  

3D модель (уровень-строка-столбец)

введите описание изображения здесь

Это тоже близко:

 np.argmin(arr, axis=0)    np.argmin(arr, axis=1)    np.argmin(arr, axis=2) 
       [0 0]                      [0 1]                       [0 1]
       [1 0]                      [1 1]                       [0 0]
  

И опять же, это работает довольно хорошо, за исключением того, что axis=1 заменяется на axis=2 .

Я не знаю, откуда взялся этот волшебный обмен, но надеюсь, что это изображение поможет OP понять, как оси связаны с измерениями.

Было бы неплохо, если бы кто-нибудь мог прокомментировать, почему мне нужно экстраординарно применять правило Swap last two axes of your expected output .

Комментарии:

1. какая отличная презентация и объяснение. Мне это понравилось. Вы правы. Это тот же способ, который я наблюдал и запомнил, пока вы были заняты созданием этого 🙂 но я хотел бы сохранить это при себе как хороший источник и ссылку. Потому что у меня все в текстовой форме и на Jupyter lol.

2. В основном это старый Mister Paint. К сожалению, нет примеров сценариев для создания этих диаграмм. Вторая диаграмма была составлена с помощью LaTeX (tikz) Paint . Я также согласен с тем, что numpy не хватает визуализации, чтобы понять это, и вам нужно нарисовать это на бумаге, если только это невозможно сделать в вашем уме.

3. большое тебе спасибо за все, чувак! вы правы в том, что не хватает numpy визуализаций, которые можно найти в Интернете. Я также сначала сделал это на бумаге, а затем сделал несколько текстовых визуализаций в своем ноутбуке Jupyter, lol.

4. @Web Development Labs Я потратил некоторое время на реализацию такого рода визуализаций. Пример, который мы обсуждали, является частью моего более крупного проекта (а именно, пример 6), вы можете увидеть и использовать его.

5. Я обязательно посмотрю на это. Кстати, приятель. Как я могу связаться с вами напрямую по электронной почте, Whatsapp или любым другим способом?