Урок курса
Конструкторы массивов: 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. Никаких заранее созданных переменных нет — вы читаете всё сами.
Что нужно сделать
Напишите программу, которая:
- Читает из
stdinодну строку с пятью целыми числами:n,start,stop,rows,cols. - Создаёт пять массивов:
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).
- Выводит в
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.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 5
Найди и исправь: неверные аргументы arange и linspace
Что уже дано
Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.
В редакторе есть сломанный код: он пытается создать два массива через np.arange и np.linspace, но оба вызова содержат ошибки — массивы получаются не той формы или не того типа, что требует задача.
Что нужно сделать
Найдите и исправьте обе ошибки в коде так, чтобы программа:
- Читала из
stdinтри целых числа в одной строке:start,stop,n. - Создавала массив
seqчерезnp.arange(start, stop, 1)с явнымdtype=float— одномерный, значения отstartдоstop - 1включительно, типfloat64. - Создавала массив
gridчерезnp.linspace(start, stop, n)— одномерный, ровноnточек, типfloat64. - Выводила в
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>
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 6
Найди и исправь: dtype-ловушки в np.full, np.zeros и np.ones
Что уже дано
Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.
В редакторе уже есть сломанный код: он создаёт три массива через np.full, np.zeros и np.ones, но в каждом вызове допущена ошибка с dtype — массивы получаются не того типа, что требует задача.
Что нужно сделать
Найдите и исправьте все три ошибки так, чтобы программа:
- Читала из
stdinодну строку с тремя целыми числами:rows,cols,val. - Создавала массив
filledчерезnp.full((rows, cols), val)с явнымdtype=float— тип должен бытьfloat64. - Создавала массив
zeroedчерезnp.zeros((rows, cols))с явнымdtype=int— тип должен быть целочисленным. - Создавала массив
onedчерезnp.ones(rows * cols)с явнымdtype=bool— тип должен бытьbool. - Выводила в
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,) для одномерных.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 7
Инвариант size: arange, linspace, zeros и ones с одинаковым числом элементов
Что уже дано
Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.
Что нужно сделать
Напишите программу, которая:
- Читает из
stdinодну строку с тремя целыми числами:start,stop,rows. - Создаёт четыре массива:
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 по умолчанию.
- Выводит в
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) для двумерных.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задачи к уроку
- NumPy zeros, ones и full: dtype — пример и задача
Разберите dtype в np.zeros, np.ones и np.full на коротком примере. Исправьте создание массивов и проверьте код без регистрации.
- NumPy arange и linspace: разница шага и количества точек
Что выбрать: np.arange или np.linspace? Сравните шаг, число точек и включение границы на примере, затем исправьте код в задаче.
Продолжить с сохранением прогресса
Перейдите к уроку в учебном кабинете.
