Skip to content

from setuptools._distutils.compat import numpy

3. Создание одномерных (1D) массивов и генерация сеток ​

Конструкторы базовых векторов ​

Создание 1D массивов из стандартных списков ​

Самый базовый способ получить одномерный массив (вектор) в NumPy — передать стандартный список Python в функцию numpy.array(). В этот момент библиотека резервирует непрерывный кусок оперативной памяти на C-уровне и копирует туда данные.

Если в списке находятся числа одного типа, массив унаследует его. Если передать пустой список, создастся массив нулевой длины с типом данных по умолчанию (обычно float64).

Инициализация через функции заполнения (zeros и ones) ​

В задачах машинного обучения часто требуется инициализировать начальными значениями веса скрытых слоев, маски внимания или векторы смещений (bias) перед запуском оптимизатора. Для этого используются встроенные конструкторы быстрого заполнения:

  • numpy.zeros(shape) — выделяет блок памяти нужного размера и заполняет его нулями. По умолчанию генерирует элементы типа float64.
  • numpy.ones(shape) — выделяет память и заполняет её единицами. Используется, например, для создания базовых масок отсечения признаков.

Инициализация без очистки памяти (empty) ​

Функция numpy.empty(shape) — это самый быстрый конструктор массивов в NumPy. В отличие от zeros, она не тратит время процессора на зануление выделенной памяти. Она просто резервирует сырой блок данных у операционной системы.

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

python
import numpy

# Create a 1D vector from a standard Python list
list_floats = [0.25, 0.5, 0.75]
numpy_vector_floats = numpy.array(list_floats)
print(f"{numpy_vector_floats = }")          # numpy_vector_floats = array([0.25, 0.5 , 0.75])
print(f"{numpy_vector_floats.shape = }")    # numpy_vector_floats.shape = (3,)

# Initialize blank placeholders for weights or biases
numpy_vector_zeros = numpy.zeros(5)
print(f"{numpy_vector_zeros = }")           # numpy_vector_zeros = array([0., 0., 0., 0., 0.])
print(f"{numpy_vector_zeros.shape = }")     # numpy_vector_zeros.shape = (5,)
numpy_vector_ones = numpy.ones(5)
print(f"{numpy_vector_ones = }")            # numpy_vector_ones = array([1., 1., 1., 1., 1.])
print(f"{numpy_vector_ones.shape = }")      # numpy_vector_ones.shape = (5,) 

# Fast allocation without initialization (contains random memory residue)
numpy_vector_empties = numpy.empty(5)
print(f"{numpy_vector_empties = }")         # numpy_vector_empties = array([1., 1., 1., 1., 1.])
print(f"{numpy_vector_empties.shape = }")   # numpy_vector_empties.shape = (5,)

Функция numpy.empty(5) выделяет в оперативной памяти место под 5 элементов, но не тратит время на их очистку или заполнение. В ячейках остается тот «мусор» (остатки данных других программ), который лежал в этих адресах памяти прямо перед вызовом функции.

Генерация числовых сеток для AI ​

Математическая генерация числовых последовательностей через arange ​

Функция numpy.arange(start, stop, step) генерирует арифметическую прогрессию в виде векторизованного массива ndarray, граница stop не включается в диапазон. Она работает аналогично стандартному встроенному range() в Python, но поддерживает дробные шаги (например, step=0.1) и выполняет генерацию на скорости скомпилированного C-кода. Незаменима для создания итерационных индексов, счетчиков эпох обучения или простых числовых последовательностей.

python
import numpy

numpy_vector_floats = numpy.arange(1,2,0.21)
print(f"{numpy_vector_floats = }")          # numpy_vector_floats = array([1.  , 1.21, 1.42, 1.63, 1.84])
print(f"{numpy_vector_floats.shape = }")    # numpy_vector_floats.shape = (5,)

ВНИМАНИЕ С ДРОБНЫМ ШАГОМ

Использование дробного шага (step) в numpy.arange сопряжено с рисками из-за особенностей округления вещественных чисел с плавающей точкой в процессоре. В некоторых случаях длина итогового массива может случайно оказаться на 1 элемент больше или меньше ожидаемой, так как значение границы stop может попасть на микроскопическую погрешность округления. Для генерации дробных сеток всегда безопаснее использовать linspace.

Создание точных числовых сеток через linspace ​

Функция numpy.linspace(start, stop, num) генерирует заданное количество (num) строго равноотстоящих (линейно распределенных) точек на отрезке между start и stop. По умолчанию обе границы включаются в результат.

python
import numpy

# Generating linearly spaced values (e.g., for plotting a function)
numpy_vector_floats = numpy.linspace(1,2,5)
print(f"{numpy_vector_floats = }")          # numpy_vector_floats = array([1.  , 1.25, 1.5 , 1.75, 2.  ])
print(f"{numpy_vector_floats.shape = }")    # numpy_vector_floats.shape = (5,)

В отличие от arange, где вы жестко задаете шаг, в linspace вы задаете желаемое количество элементов, а идеальный шаг NumPy рассчитывает автоматически. Это полностью исключает накопление ошибок округления float-чисел. Метод используется для генерации плотных линейных сеток по оси X при отрисовки графиков функций активации (Sigmoid, Tanh, ReLU) или плавных расписаний темпа обучения.

Генерация логарифмических пространств через logspace ​

Функция numpy.logspace(start, stop, num, base=10.0) генерирует заданное количество (num) точек, равноотстоящих в логарифмическом масштабе по степеням базового числа base (по умолчанию 10.0). Параметры start и stop принимают именно степени, в которые будет возводиться основание.

  • Вызов numpy.logspace(0, 3, 4) означает генерацию четырех точек: от 100 до 103. На выходе получится массив [1., 10., 100., 1000.].
python
import numpy

# Generating logarithmically spaced values (e.g., learning rates search)
numpy_vector_tens = numpy.logspace(0, 3, 4) # 10^0, 10^1, 10^2, 10^3: [1., 10.,100., 1000.]
print(f"{numpy_vector_tens = }")        # numpy_vector_tens = array([   1.,   10.,  100., 1000.])
print(f"{numpy_vector_tens.shape = }")  # numpy_vector_tens.shape = (4,)

numpy_vector_tens = numpy.logspace(0, 3, 4, base=2)
print(f"{numpy_vector_tens = }")
print(f"{numpy_vector_tens.shape = }")  # numpy_vector_tens = array([1., 2., 4., 8.])
print(f"{numpy_vector_tens.size = }")   # numpy_vector_tens.shape = (4,)

Этот метод незаменим в задачах поиска оптимальных гиперпараметров (Grid Search) для перебора коэффициентов регуляризации L1/L2 или скоростей обучения нейросетей, где значения параметров должны меняться на порядки (например, экспоненциальный перебор от 0.0001 до 0.1).

Другие современные методы создания массивов в NumPy ​

Для продвинутого управления инициализацией в NumPy используются специализированные методы, которые позволяют создавать структуры данных на основе уже существующих массивов, сохраняя их геометрию и тип данных (dtype):

  • numpy.zeros_like(other_array) — принимает на вход существующий массив и мгновенно создает новый массив точно такой же формы и типа данных, но полностью заполненный нулями.
  • numpy.ones_like(other_array) — создает массив-клон по форме и типу, заполненный единицами (используется для генерации масок под конкретный входной тензор признаков).
  • numpy.empty_like(other_array) — выделяет сырой блок памяти под параметры существующего массива без предварительной очистки.
python
import numpy

# Creating a zero mask based on another array's structure
features_tensor = numpy.array([1.5, 2.7, 3.9], dtype=numpy.float32)
blank_mask = numpy.zeros_like(features_tensor)
# Creates an array with 3 elements, filled with zeros, with dtype=float32
print(f"{features_tensor = }")  # features_tensor = array([1.5, 2.7, 3.9], dtype=float32)

Упражнения базовые (5 шт) (только с опорой на объясненную в данном уроке теорию) ​

1. Быстрое выделение буфера памяти ​

Задача: Создайте одномерный массив из 12 элементов с помощью самого быстрого конструктора, не очищающего память от системного мусора. Выведите на экран массив, форму массива и размер в байтах.

Посмотреть решение
python
import numpy

# Allocating a raw memory block for 12 items without initialization
numpy_vector_empties = numpy.empty(12)
print(f"{numpy_vector_empties = }")
print(f"{numpy_vector_empties.shape = }")
print(f"{numpy_vector_empties.nbytes = }")

Вывод подобный

text
numpy_vector_empties = array([1.19383995e-311, 3.16202013e-322, 0.00000000e+000, 0.00000000e+000,
       1.11260619e-306, 3.62942578e+179, 5.05231633e-038, 1.81501310e-052,
       1.83255737e-076, 5.98365220e+174, 1.18970000e-047, 8.93159090e+165])
numpy_vector_empties.shape = (12,)
numpy_vector_empties.nbytes = 96

2. Плотная линейная сетка для графика функции ​

Задача: Сгенерируйте сетку из 11 строго равноотстоящих точек в диапазоне от -5.0 до 5.0 включительно с помощью numpy.linspace. Этот массив имитирует ось X для отрисовки графиков функций активации нейросетей. Выведите на экран массив, форму массива и размер в байтах.

Посмотреть решение
python
import numpy

# Generating 11 linear steps across the symmetric range
x_axis_grid = numpy.linspace(-5.0, 5.0, 11)
print(x_axis_grid)          # Outputs: [-5. -4. -3. -2. -1.  0.  1.  2.  3.  4.  5.]
print(x_axis_grid.shape)    # (11,)
print(x_axis_grid.nbytes)   # 88

Задача: С помощью функции numpy.logspace создайте массив из 4 точек в логарифмическом масштабе основания 10 в диапазоне степеней от -4 до -1 включительно. Этот массив будет представлять собой сетку тестируемых скоростей обучения моделей (10−4,10−3,10−2,10−1). Выведите результат.

Посмотреть решение
python
import numpy

# Creating logarithmic search grid for optimization
learning_rates = numpy.logspace(-4, -1, 4)
print(learning_rates)  # Outputs: [0.0001 0.001  0.01   0.1   ]

4. Создание нулевой маски на основе существующего вектора ​

Задача: Дан вектор признаков input_features = numpy.array([0.15, -0.82, 0.44], dtype=numpy.float32). Используя специализированный метод _like, создайте для него маску, заполненную нулями, которая автоматически унаследует размер и тип данных float32. Выведите вектор и тип данных элементов вектора.

Посмотреть решение
python
import numpy

input_features = numpy.array([0.15, -0.82, 0.44], dtype=numpy.float32)

# Generating a zero array matching the exact properties of the input
target_mask = numpy.zeros_like(input_features)
print(target_mask)       # Outputs: [0. 0. 0.]
print(target_mask.dtype) # Outputs: float32

5. Создание вектора единичных масок ​

Задача: Инициализируйте одномерный массив из 7 элементов, заполненный исключительно единицами типа float, с помощью встроенной функции заполнения. Выведите полученный вектор на экран и тип данных элементов вектора.

Посмотреть решение
python
import numpy

# Generating initial uniform unit masks vector
unit_mask = numpy.ones(7)
print(unit_mask)  # Outputs: [1. 1. 1. 1. 1. 1. 1.]
print(unit_mask.dtype)