0

В NumPy, что делает выбор с помощью [:, None]?

13

Я прохожу курс по глубокому обучению на 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 ответ(ов)

0

В коде опытных пользователей NumPy вы часто можете увидеть специальный синтаксис среза вместо вызова функции reshape.

x = v[None, :]

или

x = v[:, None]

Эти строки создают срез, который обращается ко всем элементам массива v, но при этом указывает NumPy добавить новое измерение размером 1 для соответствующего оси. Это позволяет удобно манипулировать формой массива и часто используется для подготовки данных к дальнейшим вычислениям.

0

В 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 помогает изменять размерность массива, позволяя выполнять операции, которые требуют согласования размеров.

0

Чтобы объяснить простыми словами, это позволяет выполнять операции между массивами с разным количеством измерений.

Это делается путем добавления нового пустого измерения, которое автоматически подгоняется под размер другого массива.

То есть, если:

Array1 = shape[100]
Array2 = shape[10, 100]

то операция Array1 * Array2 обычно приведет к ошибке.

Однако Array1[:, None] * Array2 будет работать корректно.

0

Чтобы прояснить ответ от @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 как строковые или столбцовые векторы, что поможет избежать потенциальных ошибок в дальнейшем.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь