Урок курса

Конструкторы массивов: arange, linspace, zeros, ones, full

NumPy и pandas: практический тренажёр

В прошлом уроке мы создавали массивы из готовых списков через np.array и сразу проверяли результат через .shape и .dtype. Теперь задача другая: построить массив не из данных, которые уже есть, а с нуля — по правилу. Именно для этого в NumPy существуют конструкторы.

Числовые последовательности: np.arange и np.linspace

Два самых частых случая — «дай мне числа с таким-то шагом» и «дай мне ровно N точек в таком-то диапазоне». Это разные задачи, и под каждую есть свой конструктор.

np.arange: задаёшь шаг — получаешь последовательность

np.arange(start, stop, step) работает как встроенный range, только возвращает массив NumPy. Граница stop в результат не попадает.

import numpy as np

a = np.arange(0, 10, 2)
print(a)        # [0 2 4 6 8]
print(a.shape)  # (5,)
print(a.dtype)  # целочисленный dtype (например, int64 на большинстве платформ)

Поскольку все аргументы целые, NumPy выводит целочисленный dtype. Конкретная ширина (32 или 64 бита) зависит от платформы; если нужен точный тип, задавайте его явно. Если хотя бы один аргумент дробный, dtype автоматически становится float64:

b = np.arange(0, 1, 0.3)
print(b)        # [0.  0.3  0.6  0.9]
print(b.dtype)  # float64

Сколько элементов окажется в массиве — зависит от шага и диапазона. Это не всегда очевидно при дробных аргументах из-за особенностей арифметики с плавающей точкой. Если нужно точное количество точек, лучше использовать linspace.

np.linspace: задаёшь количество точек — получаешь равномерную сетку

np.linspace(start, stop, num) возвращает ровно num равноудалённых точек от start до stop, причём обе границы включены.

c = np.linspace(0, 1, 5)
print(c)        # [0.   0.25 0.5  0.75 1.  ]
print(c.shape)  # (5,)
print(c.dtype)  # float64

linspace всегда возвращает float64 при обычных числовых границах — независимо от того, целые они или нет. Количество элементов всегда точно равно num: никаких неожиданностей из-за округлений.

Когда что использовать

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

  • arange — когда известен нужный шаг между элементами, а количество точек вычисляется из диапазона и шага. Граница stop не включается.
  • linspace — когда важно получить ровно N точек, а шаг NumPy вычислит сам. Обе границы включены.

Ключевое различие: в arange вы управляете шагом; в linspace — количеством точек. Если нужен предсказуемый размер массива без зависимости от дробной арифметики — выбирайте linspace.

Массивы заданной формы: np.zeros, np.ones и np.full

Конструкторы arange и linspace строят последовательности — их смысл в числах, которые они порождают. zeros, ones и full работают иначе: ты задаёшь форму массива, а значения — вторичны. Это инструменты для резервирования структуры.

np.zeros и np.ones

Оба принимают один обязательный аргумент — shape. Для одномерного массива достаточно передать целое число; для многомерного — кортеж.

import numpy as np

# Одномерный: передаём целое число
z1 = np.zeros(5)
print(z1)        # [0. 0. 0. 0. 0.]
print(z1.shape)  # (5,)

# Двумерный: передаём кортеж (строки, столбцы)
z2 = np.zeros((2, 3))
print(z2)
# [[0. 0. 0.]
#  [0. 0. 0.]]
print(z2.shape)  # (2, 3)

По умолчанию оба конструктора возвращают float64. Это важно: если ты ждёшь целых чисел, а видишь 0. вместо 0 — это не ошибка, это поведение по умолчанию.

o = np.ones((3, 2))
print(o.dtype)   # float64

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

np.full

np.full(shape, fill_value) — обобщение zeros и ones: заполняет массив любым заданным значением.

# Двумерный массив 2×4, заполненный семёрками
f1 = np.full((2, 4), 7)
print(f1)
# [[7 7 7 7]
#  [7 7 7 7]]
print(f1.dtype)  # целочисленный dtype — NumPy вывел тип из fill_value=7

# Тот же shape, но с дробным значением
f2 = np.full((3,), 3.14)
print(f2)        # [3.14 3.14 3.14]
print(f2.dtype)  # float64

full отличается от zeros/ones в одном месте: его dtype по умолчанию выводится из fill_value, а не фиксирован как float64. Передашь целое — получишь целочисленный массив; передашь 3.14 — получишь float64. Конкретная ширина целочисленного типа (например, int32 или int64) зависит от платформы; если нужен точный тип, укажи его явно: np.full((2, 4), 7, dtype=np.int64).

Как задавать shape

Во всех трёх конструкторах правило одно:

  • целое число → одномерный массив такой длины;
  • кортеж (m, n) → двумерный массив из m строк и n столбцов;
  • кортеж (m, n, k) → трёхмерный, и так далее.

Если передать кортеж из одного числа — (5,) — результат будет таким же, как при передаче просто 5: одномерный массив из пяти элементов.

После создания всегда полезно проверить .shape и .dtype — особенно когда форма задаётся программно, а не вручную.

Явное управление dtype во всех пяти конструкторах

У каждого конструктора есть своё поведение dtype по умолчанию, и важно его знать — не чтобы запомнить наизусть, а чтобы не удивляться результату.

Правила сводятся к четырём случаям:

  • np.arange выводит тип из аргументов: целые → целочисленный dtype, хотя бы один дробный → float64.
  • np.linspace всегда возвращает float64 при обычных числовых границах — независимо от того, целые они или нет.
  • np.zeros и np.ones всегда возвращают float64, если не указать иное.
  • np.full выводит тип из fill_value: передал 7 — получишь целочисленный массив, передал 7.0 — получишь float64.

Это значит, что np.zeros((3,)) и np.full((3,), 0) дадут разные dtype: первый — float64, второй — целочисленный. Выглядят похоже, ведут себя по-разному.

Когда поведение по умолчанию не устраивает, все пять конструкторов принимают параметр dtype=:

import numpy as np

# zeros по умолчанию — float64; нужен целочисленный тип
a = np.zeros((3,), dtype=int)
print(a)        # [0 0 0]
print(a.dtype)  # целочисленный dtype (конкретная ширина зависит от платформы)

# arange с целыми аргументами — целочисленный; нужен float
b = np.arange(0, 5, dtype=float)
print(b)        # [0. 1. 2. 3. 4.]
print(b.dtype)  # float64

# linspace всегда float64; при желании можно сделать float32
c = np.linspace(0, 1, 5, dtype='float32')
print(c.dtype)  # float32

# ones по умолчанию — float64; нужен bool
d = np.ones((4,), dtype=bool)
print(d)        # [ True  True  True  True]

# full с целым fill_value — целочисленный; нужен float
e = np.full((2, 3), 9, dtype=float)
print(e.dtype)  # float64

Если нужен гарантированно конкретный целочисленный тип, задавайте его явно — например, dtype=np.int64 — вместо dtype=int, чтобы результат не зависел от платформы.

На практике dtype= чаще всего нужен в двух ситуациях. Первая — когда следующая операция или формат данных требует определённого типа: например, индексные массивы должны быть целочисленными, а конкретная библиотечная функция может ожидать float32 или float64 согласно своему контракту. Вторая — когда важна память: float32 занимает вдвое меньше, чем float64, и для больших массивов это ощутимо.

Если указать dtype=, NumPy сделает приведение типа сразу при создании массива. Попытка сохранить 3.14 в массив с dtype=int не приведёт к ошибке — значение просто обрежется до 3. Это молчаливое поведение, о котором стоит помнить.

Сравнительный разбор пяти конструкторов: shape, dtype, значения

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

  • Нужен заданный шаг и невключаемая правая граница — используйте np.arange.
  • Нужно ровно заданное число равномерных точек с обеими границами — np.linspace.
  • Нужен массив указанной формы, заполненный нулями или единицами — np.zeros или np.ones.
  • Нужен массив указанной формы с другой константой — np.full.

Например, для требований «шесть целых чисел от 0 с шагом 2», «пять точек от 0 до 1 включительно» и «матрица 2×3, заполненная −1» подходят разные выражения:

import numpy as np

a = np.arange(0, 12, 2, dtype=np.int64)
b = np.linspace(0, 1, 5)
c = np.full((2, 3), -1, dtype=np.int64)

print(a)          # [ 0  2  4  6  8 10]
print(b)          # [0.   0.25 0.5  0.75 1.  ]
print(c.shape)    # (2, 3)
print(c.dtype)    # int64

Проверка .shape отвечает на вопрос, получена ли нужная структура, а .dtype — соответствует ли тип контракту следующей операции. Если точная ширина типа важна, задавайте её явно через dtype, как в примерах a и c.

Задача 1

Вы вызываете np.linspace(0, 1, 5) — обе границы целые числа. Какой dtype будет у результирующего массива?

Выберите один вариант
Без регистрации · результат не сохраняется

Задача 2

Программист хочет создать массив shape (3, 3), заполненный значением 0.5. Какой из вызовов корректно решает задачу?

Выберите один вариант
Без регистрации · результат не сохраняется

Задача 3

Какой вызов создаёт массив [0., 0.5, 1., 1.5, 2.] с явным dtype float64?

Выберите один вариант
Без регистрации · результат не сохраняется

Задача 4

Пять конструкторов: shape, dtype и размер по заданным параметрам

Что уже дано

Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.

Что нужно сделать

Напишите программу, которая:

  1. Читает из stdin одну строку с пятью целыми числами: n, start, stop, rows, cols.
  2. Создаёт пять массивов:
  • a — через np.arange(start, stop, 1) с явным dtype=float;
  • b — через np.linspace(start, stop, n);
  • c — через np.zeros((rows, cols)) с явным dtype=int;
  • d — через np.ones((rows, cols));
  • e — через np.full((rows, cols), n).
  1. Выводит в stdout пять строк — по одной на каждый массив — в формате:
<имя>: shape=<shape> dtype=<dtype>

где <имя> — буква a, b, c, d, e соответственно.

Формат shape — строго как у Python: (n,) для одномерных, (r, c) для двумерных.

Ввод и вывод

Программа читает stdin и пишет в stdout.

Формат ввода

Одна строка: пять целых чисел через пробел: n start stop rows cols.

Гарантируется: stop > start, n >= 2, rows >= 1, cols >= 1.

Формат вывода

Пять строк вида <буква>: shape=<shape> dtype=<dtype>. Порядок: a, b, c, d, e.

РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Задача 5

Найди и исправь: неверные аргументы arange и linspace

Что уже дано

Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.

В редакторе есть сломанный код: он пытается создать два массива через np.arange и np.linspace, но оба вызова содержат ошибки — массивы получаются не той формы или не того типа, что требует задача.

Что нужно сделать

Найдите и исправьте обе ошибки в коде так, чтобы программа:

  1. Читала из stdin три целых числа в одной строке: start, stop, n.
  2. Создавала массив seq через np.arange(start, stop, 1) с явным dtype=float — одномерный, значения от start до stop - 1 включительно, тип float64.
  3. Создавала массив grid через np.linspace(start, stop, n) — одномерный, ровно n точек, тип float64.
  4. Выводила в stdout ровно две строки:
  • seq: size=<size> dtype=<dtype> first=<first_element>
  • grid: size=<size> dtype=<dtype> last=<last_element>

Где <first_element> — первый элемент seq, <last_element> — последний элемент grid, оба выводятся как float через str() (т.е. стандартный Python-вывод числа с плавающей точкой).

Ввод и вывод

Программа читает stdin и пишет в stdout.

Формат ввода

Одна строка: три целых числа через пробел: start stop n.

Гарантируется: stop > start, n >= 2.

Формат вывода

Две строки:

seq: size=<size> dtype=<dtype> first=<first_element>
grid: size=<size> dtype=<dtype> last=<last_element>
РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Задача 6

Найди и исправь: dtype-ловушки в np.full, np.zeros и np.ones

Что уже дано

Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.

В редакторе уже есть сломанный код: он создаёт три массива через np.full, np.zeros и np.ones, но в каждом вызове допущена ошибка с dtype — массивы получаются не того типа, что требует задача.

Что нужно сделать

Найдите и исправьте все три ошибки так, чтобы программа:

  1. Читала из stdin одну строку с тремя целыми числами: rows, cols, val.
  2. Создавала массив filled через np.full((rows, cols), val) с явным dtype=float — тип должен быть float64.
  3. Создавала массив zeroed через np.zeros((rows, cols)) с явным dtype=int — тип должен быть целочисленным.
  4. Создавала массив oned через np.ones(rows * cols) с явным dtype=bool — тип должен быть bool.
  5. Выводила в stdout три строки — по одной на каждый массив — в формате:
filled: shape=<shape> dtype=<dtype>
zeroed: shape=<shape> dtype=<dtype>
oned: shape=<shape> dtype=<dtype>

Ввод и вывод

Программа читает stdin и пишет в stdout.

Формат ввода

Одна строка: три целых числа через пробел: rows cols val.

Гарантируется: rows >= 1, cols >= 1, val >= 1.

Формат вывода

Три строки вида <имя>: shape=<shape> dtype=<dtype>. Порядок: filled, zeroed, oned.

Формат shape — строго как у Python: (r, c) для двумерных, (n,) для одномерных.

РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Задача 7

Инвариант size: arange, linspace, zeros и ones с одинаковым числом элементов

Что уже дано

Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.

Что нужно сделать

Напишите программу, которая:

  1. Читает из stdin одну строку с тремя целыми числами: start, stop, rows.
  2. Создаёт четыре массива:
  • seq — через np.arange(start, stop, 1) с явным dtype=float; количество элементов равно stop - start.
  • grid — через np.linspace(start, stop - 1, stop - start); ровно stop - start точек.
  • zmat — через np.zeros((rows, (stop - start) // rows)) с явным dtype=int; двумерный, shape (rows, cols), где cols = (stop - start) // rows.
  • omat — через np.ones((rows, (stop - start) // rows)); двумерный, тот же shape, dtype по умолчанию.
  1. Выводит в stdout четыре строки — по одной на каждый массив — в формате:
<имя>: shape=<shape> size=<size> dtype=<dtype>

Порядок: seq, grid, zmat, omat.

Гарантируется: stop > start, (stop - start) делится на rows нацело, rows >= 1.

Ввод и вывод

Программа читает stdin и пишет в stdout.

Формат ввода

Одна строка: три целых числа через пробел: start stop rows.

Формат вывода

Четыре строки вида <имя>: shape=<shape> size=<size> dtype=<dtype>. Формат shape — строго как у Python: (n,) для одномерных, (r, c) для двумерных.

РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Задачи к уроку

Все задачи курса →

Продолжить с сохранением прогресса

Перейдите к уроку в учебном кабинете.

Перейти к интерактивному уроку