В NumPy, что делает выбор с помощью [:, None]?
Я прохожу курс по глубокому обучению на Udacity и столкнулся со следующим кодом:
def reformat(dataset, labels):
dataset = dataset.reshape((-1, image_size * image_size)).astype(np.float32)
# Преобразуем 0 в [1.0, 0.0, 0.0 ...], 1 в [0.0, 1.0, 0.0 ...]
labels = (np.arange(num_labels) == labels[:,None]).astype(np.float32)
return dataset, labels
Существует ли у кого-то понимание, что делает labels[:,None]
в данном контексте?
4 ответ(ов)
В коде опытных пользователей NumPy вы часто можете увидеть специальный синтаксис среза вместо вызова функции reshape
.
x = v[None, :]
или
x = v[:, None]
Эти строки создают срез, который обращается ко всем элементам массива v
, но при этом указывает NumPy добавить новое измерение размером 1 для соответствующего оси. Это позволяет удобно манипулировать формой массива и часто используется для подготовки данных к дальнейшим вычислениям.
В NumPy
объект newaxis
можно использовать во всех операциях извлечения, чтобы создать ось длиной один. newaxis
является псевдонимом для None
, и None
может быть использован вместо этого с тем же результатом.
Для демонстрации на части вашего кода:
import numpy as np
labels = np.array([1, 3, 5])
# Добавляем новую ось
print(labels[:, None])
# Вывод:
# array([[1],
# [3],
# [5]])
# Сравниваем с диапазоном от 0 до 7, добавив новую ось
print(np.arange(8) == labels[:, None])
# Вывод:
# array([[False, True, False, False, False, False, False, False],
# [False, False, False, True, False, False, False, False],
# [False, False, False, False, False, True, False, False]], dtype=bool)
# Преобразуем булев массив в целочисленный
print((np.arange(8) == labels[:, None]).astype(int))
# Вывод:
# array([[0, 1, 0, 0, 0, 0, 0, 0],
# [0, 0, 0, 1, 0, 0, 0, 0],
# [0, 0, 0, 0, 0, 1, 0, 0]])
Таким образом, newaxis
помогает изменять размерность массива, позволяя выполнять операции, которые требуют согласования размеров.
Чтобы объяснить простыми словами, это позволяет выполнять операции между массивами с разным количеством измерений.
Это делается путем добавления нового пустого измерения, которое автоматически подгоняется под размер другого массива.
То есть, если:
Array1 = shape[100]
Array2 = shape[10, 100]
то операция Array1 * Array2
обычно приведет к ошибке.
Однако Array1[:, None] * Array2
будет работать корректно.
Чтобы прояснить ответ от @GWW и комментарий от @BlueRine S: при работе с массивами numpy целесообразно четко различать одномерные массивы как строковые или столбцовые векторы. Это также подчеркивал Андрей Нг, чтобы избежать ошибок в коде.
Вот пример:
>>> import numpy as NP
>>> a = NP.arange(1, 5)
>>> a
array([1, 2, 3, 4])
>>> a.shape
(4,)
Как видно, массив a
является одномерным с формой (4,)
.
Теперь, если мы хотим представить его как столбцовый вектор, мы можем использовать None
:
>>> a[:, None].shape
(4, 1)
>>> a[:, None]
array([[1],
[2],
[3],
[4]])
Здесь a[:, None]
изменяет форму массива на (4, 1)
, что соответствует столбцовому вектору.
С другой стороны, если мы хотим представить его как строковый вектор, мы можем сделать следующее:
>>> a[None, :].shape
(1, 4)
>>> a[None, :]
array([[1, 2, 3, 4]])
Здесь a[None, :]
изменяет форму на (1, 4)
— это строковый вектор.
Также мы можем использовать np.reshape
для изменения формы:
>>> np.reshape(a, (1, -1))
array([[1, 2, 3, 4]])
>>> np.reshape(a, (-1, 1))
array([[1],
[2],
[3],
[4]])
В результате, в зависимости от контекста использования, вы можете представлять одномерные массивы numpy как строковые или столбцовые векторы, что поможет избежать потенциальных ошибок в дальнейшем.
Наиболее эффективный способ применения функции к массиву NumPy
Как извлечь частоту, связанную с FFT значениями в Python?
Цветовой график 2D массива в matplotlib
Преобразование байтового массива обратно в массив numpy
Взвешенный процентиль с помощью numpy