Зачем нам нужно np.squeeze()?

Очень часто массивы сжимаются с помощью np.squeeze(). В документации говорится:

Удалить одномерные записи из формы.

Однако мне все еще интересно: почему нулевые и неразмерные записи в форме a? Или иначе: зачем существуют a.shape = (2,1) и (2,)?

Ответ 1

Помимо математических различий между двумя вещами, существует проблема предсказуемости. Если ваше предложение было выполнено, вы ни в коем случае не могли полагаться на измерение вашего массива. Поэтому любое выражение формы my_array[x,y] должно быть заменено на то, что сначала проверяет, является ли my_array фактически двумерным и в какой-то момент не имеет неявного squeeze. Это, вероятно, будет запутывать код намного больше, чем случайный squeeze, который делает четко определенную вещь.

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

В духе Zen of Python, также Explicit is better than implicit, мы также можем сказать, что мы должны предпочесть явно squeeze неявным преобразование массива.

Ответ 2

Одним из примеров важности является умножение массивов. Два двумерных массива будут умножать каждое значение за раз

например.

>>> x = np.ones((2, 1))*2
>>> y = np.ones((2, 1))*3
>>> x.shape
(2,1)
>>> x*y
array([[ 6.],
       [ 6.]])

Если вы умножаете 1d-массив на 2d-массив, то поведение отличается

>>> z = np.ones((2,))*3
>>> x*z
array([[ 6.,  6.],
       [ 6.,  6.]])

Во-вторых, вы также можете захотеть сжать ранние размеры, например. a.shape = (1,2,2) - a.shape = (2,2)

Ответ 3

Когда вы сжимаете массив (2,1), вы получаете (2,), который работает как (2,1), так и (1,2):

>>> a = np.ones(2)
>>> a.shape
(2,)
>>> a.T.shape
(2,)
>>> X = np.ones((2,2))*2
>>> np.dot(a,X)
[4. 4.]
>>> np.dot(X,a)
[4. 4.]

Этого не может быть с массивом (2,1):

>>> b = np.ones((2,1))
>>> np.dot(b,X)
Traceback (most recent call last):
ValueError: shapes (2,1) and (2,2) not aligned: 1 (dim 1) != 2 (dim 0)

Ответ 4

Это поможет вам избавиться от бесполезных одномерных массивов, таких как использование [7,8,9] вместо [[[7,8,9]]] или [[1,2,3],[4,5,6]] вместо [[[[1,2,3],[4,5,6]]]]. Посмотрите эту ссылку из учебника, например.