Как работает параметр оси из NumPy?

Может ли кто-нибудь объяснить, что именно делает параметр axis в NumPy?

Я ужасно смущен.

Я пытаюсь использовать функцию myArray.sum(axis=num)

Сначала я подумал, что если сам массив имеет 3 измерения, axis=0 вернет три элемента, состоящие из суммы всех вложенных элементов в той же позиции. Если бы каждое измерение содержало пять измерений, я ожидал, что axis=1 вернет результат из пяти элементов и так далее.

Однако это не так, и документация не очень помогает мне (они используют массив 3x3x3, так что это трудно сказать, что происходит)

Вот что я сделал:

>>> e
array([[[1, 0],
        [0, 0]],

       [[1, 1],
        [1, 0]],

       [[1, 0],
        [0, 1]]])
>>> e.sum(axis = 0)
array([[3, 1],
       [1, 1]])
>>> e.sum(axis=1)
array([[1, 0],
       [2, 1],
       [1, 1]])
>>> e.sum(axis=2)
array([[1, 0],
       [2, 1],
       [1, 1]])
>>>

Очевидно, что результат не является интуитивным.


person CodyBugstein    schedule 11.03.2014    source источник


Ответы (6)


Четко,

e.shape == (3, 2, 2)

Сумма по оси — это операция сокращения, поэтому указанная ось исчезает. Следовательно,

e.sum(axis=0).shape == (2, 2)
e.sum(axis=1).shape == (3, 2)
e.sum(axis=2).shape == (3, 2)
person Martin    schedule 11.03.2014
comment
Я не понимаю - почему пропадает указанная ось? - person CodyBugstein; 12.03.2014
comment
Если у вас есть вектор и суммируйте его элементы, вы получите число. Из одномерного массива вы получаете скаляр. Вот как это исчезает. - person Martin; 26.03.2014
comment
@CodyBugstein Ось исчезает, потому что sum является операцией агрегирования, а это означает, что когда вы суммируете n элементов, вы получаете только 1. Таким образом, после суммирования все элементы вдоль этой оси сворачиваются до одного элемента. Представьте, что вы комкаете прямоугольный лист бумаги в горизонтальную линию (или вид сигары). Если вы нарисовали на своем листе сетку чисел, все вертикальные элементы окажутся вместе; остается только горизонтальное измерение. - person Benjamin Crouzier; 19.10.2017
comment
Эй, Мартин! Спасибо мужик за ответ!! Я действительно запутался, как работает параметр оси. Но этот точный ответ всего в 5 строках делает все кристально ясным. Теперь у меня есть измерение, которое исчезнет! - person blitu12345; 18.02.2019

Чтобы понять axis интуитивно, обратитесь к изображению ниже (источник: Physic Dept, Cornell Uni)

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

Форма (логического) массива на рисунке выше — shape=(8, 3). ndarray.shape вернет кортеж, где записи соответствуют длине определенного измерения. В нашем примере 8 соответствует длине оси 0, тогда как 3 соответствует длине оси 1.

person kmario23    schedule 09.01.2018
comment
Это лучше понять, чем просто заставить ось исчезнуть. Исчезновение оси — это следствие, а не причина. Если вы ожидаете, что ось исчезнет, ​​вы будете раздражены, когда попытаетесь использовать такие операции, как sort. - person off99555; 02.06.2020

Если кому-то нужно это визуальное описание:

пустая ось

person debaonline4u    schedule 25.09.2018
comment
Здесь вы также можете следить: stackoverflow.com/ вопросы/22149584/ - person debaonline4u; 25.09.2018

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

Вы можете создать массив произвольного размера с помощью numpy. Например, вот 5-мерный массив:

>>> a = np.random.rand(2, 3, 4, 5, 6)
>>> a.shape
(2, 3, 4, 5, 6)

Вы можете получить доступ к любому элементу этого массива, указав индексы. Например, вот первый элемент этого массива:

>>> a[0, 0, 0, 0, 0]
0.0038908603263844155

Теперь, если вы уберете одно из измерений, вы получите количество элементов в этом измерении:

>>> a[0, 0, :, 0, 0]
array([0.00389086, 0.27394775, 0.26565889, 0.62125279])

Когда вы применяете такую ​​функцию, как sum с параметром axis, это измерение удаляется и создается массив меньшего размера, чем исходный. Для каждой ячейки в новом массиве оператор получит список элементов и применит функцию редукции, чтобы получить масштабатор.

>>> np.sum(a, axis=2).shape
(2, 3, 5, 6)

Теперь вы можете проверить, что первый элемент этого массива является суммой вышеуказанных элементов:

>>> np.sum(a, axis=2)[0, 0, 0, 0]
1.1647502999560164

>>> a[0, 0, :, 0, 0].sum()
1.1647502999560164

axis=None имеет особое значение для выравнивания массива и применения функции ко всем числам.

Теперь вы можете подумать о более сложных случаях, когда ось — это не просто число, а кортеж:

>>> np.sum(a, axis=(2,3)).shape
(2, 3, 6)

Обратите внимание, что мы используем ту же технику, чтобы выяснить, как было выполнено это сокращение:

>>> np.sum(a, axis=(2,3))[0,0,0]
7.889432081931909

>>> a[0, 0, :, :, 0].sum()
7.88943208193191

Вы также можете использовать те же рассуждения для добавления измерения в массив вместо уменьшения измерения:

>>> x = np.random.rand(3, 4)
>>> y = np.random.rand(3, 4)

# New dimension is created on specified axis
>>> np.stack([x, y], axis=2).shape
(3, 4, 2)
>>> np.stack([x, y], axis=0).shape
(2, 3, 4)

# To retrieve item i in stack set i in that axis 

Надеюсь, это даст вам общее и полное представление об этом важном параметре.

person Shital Shah    schedule 20.11.2018

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

Основной источник путаницы связан с такими выражениями, как «Ось, вдоль которой вычисляются средние значения», которая является документацией аргумента axis функции numpy.mean. Что, черт возьми, здесь означает «вдоль которого»? «По которому» по существу означает, что вы суммируете строки (и делите на количество строк, учитывая, что мы вычисляем среднее значение), если ось равна 0, и столбцы, если ось равна 1. В случае ось равна 0 (или 1), строки могут быть скалярами, векторами или даже другими многомерными массивами.

In [1]: import numpy as np

In [2]: a=np.array([[1, 2], [3, 4]])

In [3]: a
Out[3]: 
array([[1, 2],
       [3, 4]])

In [4]: np.mean(a, axis=0)
Out[4]: array([2., 3.])

In [5]: np.mean(a, axis=1)
Out[5]: array([1.5, 3.5])

Итак, в приведенном выше примере np.mean(a, axis=0) возвращает array([2., 3.]), потому что (1 + 3)/2 = 2 и (2 + 4)/2 = 3. Он возвращает массив из двух чисел, потому что он возвращает среднее значение строк для каждого столбца (а столбцов два).

person nbro    schedule 29.10.2019

И 1-й, и 2-й ответ отлично подходят для понимания концепции ndarray в numpy. Я привожу простой пример.

И судя по этому изображению @debaonline4u

https://i.stack.imgur.com/O5hBF.jpg

Предположим, у вас есть двумерный массив - [1, 2, 3] [4, 5, 6]

В формате numpy это будет -

c = np.array([[1, 2, 3], 
              [4, 5, 6]])  

Сейчас,

c.ndim = 2 (rows/axis=0)
c.shape = (2,3) (axis0, axis1)
c.sum(axis=0) = [1+4, 2+5, 3+6] = [5, 7, 9] (sum of the 1st elements of each rows, so along axis0)
c.sum(axis=1) = [1+2+3, 4+5+6] = [6, 15]    (sum of the elements in a row, so along axis1)

Итак, для вашего трехмерного массива 3d сумма массива Numpy

person 33Anika33    schedule 24.06.2020