Урок курса
ndarray: создание из последовательностей и атрибуты структуры
NumPy и pandas: практический тренажёрNumPy — это фундамент почти всего числового Python: pandas строит DataFrame поверх него, scikit-learn принимает массивы на вход, а большинство библиотек визуализации ожидают именно numpy-совместимые данные. Центральный объект здесь — ndarray, и с него и начнём.
ndarray как однородный многомерный контейнер
Python-список — гибкая штука: в него можно положить int, строку и ещё один список одновременно. Именно за счёт этой гибкости CPython хранит каждый элемент как отдельный Python-объект с собственным заголовком и счётчиком ссылок. Цена — дополнительная память и медленный доступ при числовых вычислениях.
ndarray устроен принципиально иначе. Его ключевое свойство — однородность: все элементы имеют одинаковый тип данных (dtype), единый для всего массива. Это позволяет NumPy хранить данные компактно и применять к ним векторизованные операции без перебора разнотипных Python-объектов. Физическое расположение данных в памяти — отдельная тема, которая выходит за рамки этого урока; для понимания ndarray достаточно знать, что однородный dtype — это фундаментальное свойство, а не деталь реализации.
Второе обязательное свойство — прямоугольность. Двумерный ndarray — это таблица, где все строки имеют одинаковое количество столбцов. «Рваных» строк разной длины в ndarray быть не может: если передать в np.array вложенные списки разной длины, NumPy поднимет ValueError и не создаст двумерный числовой массив. Это не ограничение, а гарантия: именно прямоугольная структура позволяет описывать форму массива одним кортежем чисел и применять операции ко всем элементам сразу.
Тип элементов — dtype — фиксируется в момент создания массива и единый для всего массива. Если передать список целых чисел, NumPy выберет целочисленный dtype. Если среди элементов окажется хотя бы одно число с плавающей точкой, весь массив станет вещественным — NumPy автоматически приведёт все значения к более широкому типу. Смешать int и строку в одном ndarray без потерь не получится: строки вытеснят числа в Unicode-тип, и арифметика станет недоступна.
Подытоживая модель: ndarray — это прямоугольный массив с элементами одного dtype, форма которого задаётся кортежем целых чисел. Всё остальное в NumPy — конструкторы, операции, индексирование — строится на этой модели.
Создание одномерного и двумерного ndarray через np.array
Единственная функция, которая нужна для старта — np.array(). Она принимает любую Python-последовательность и превращает её в ndarray.
Для одномерного массива передаём плоский список:
import numpy as np
a1 = np.array([10, 20, 30])
print(a1)
# [10 20 30]
Вывод уже отличается от Python-списка: нет запятых — это сигнал, что мы работаем с ndarray, а не с обычным list.
Для двумерного массива передаём вложенный список — список строк, где каждая строка сама является списком одинаковой длины:
a2 = np.array([[1, 2, 3],
[4, 5, 6]])
print(a2)
# [[1 2 3]
# [4 5 6]]
NumPy интерпретирует внешний список как набор строк, а каждый внутренний список — как строку таблицы. Длины внутренних списков обязаны совпадать — иначе прямоугольной формы не получится.
Автоматический вывод dtype. NumPy смотрит на переданные значения и выбирает тип самостоятельно. Если все элементы — целые числа Python, получится целочисленный dtype. Стоит добавить хотя бы одно число с точкой — и весь массив становится вещественным:
a_int = np.array([1, 2, 3])
a_float = np.array([1, 2, 3.0]) # одна точка меняет тип всего массива
print(a_int.dtype) # целочисленный dtype, например int32 или int64 — зависит от платформы
print(a_float.dtype) # float64
Это прямое следствие однородности: NumPy обязан выбрать один тип для всего массива, поэтому берёт наиболее широкий из присутствующих. Конкретная ширина целочисленного dtype при автоматическом выводе зависит от платформы и сборки NumPy — если вам нужен гарантированный тип, задайте его явно.
Если нужен конкретный тип — передаём его явно через параметр dtype:
a_i64 = np.array([1, 2, 3], dtype=np.int64)
a_f32 = np.array([1, 2, 3], dtype=np.float32)
print(a_i64.dtype) # int64
print(a_f32.dtype) # float32
Явное указание dtype полезно, когда важна воспроизводимость поведения на разных платформах, когда нужна экономия памяти или когда последующий код ожидает строго определённый тип.
Посмотрим на оба массива вместе и убедимся, что NumPy создал именно то, что ожидалось:
print(a1) # [10 20 30]
print(type(a1)) # <class 'numpy.ndarray'>
print(a2)
# [[1 2 3]
# [4 5 6]]
print(type(a2)) # <class 'numpy.ndarray'>
Оба объекта — экземпляры numpy.ndarray. Отсюда следует следующий вопрос: как узнать форму, количество измерений и общее число элементов уже созданного массива? Для этого у ndarray есть набор атрибутов, которые мы разберём в следующей секции.
Атрибуты структуры массива: shape, ndim, size, dtype
Когда массив уже создан, нужно уметь быстро ответить на три вопроса: какова его форма, сколько у него измерений и сколько в нём элементов. Плюс — какой у него тип данных. Для этого у любого ndarray есть четыре атрибута: shape, ndim, size и dtype.
Возьмём массивы из предыдущего примера и считаем все четыре атрибута:
import numpy as np
a1 = np.array([10, 20, 30], dtype=np.int64)
a2 = np.array([[1, 2, 3],
[4, 5, 6]], dtype=np.int64)
print(a1.shape, a1.ndim, a1.size, a1.dtype)
# (3,) 1 3 int64
print(a2.shape, a2.ndim, a2.size, a2.dtype)
# (2, 3) 2 6 int64
В этом примере dtype=np.int64 задан явно, поэтому последнее поле вывода одинаково на любой платформе. Всё остальное (shape, ndim, size) одинаково на любой платформе.
shape — кортеж целых чисел, по одному числу на каждое измерение. Для a1 это (3,): одно измерение, три элемента в нём. Запятая после 3 не опечатка — она нужна, чтобы Python понял, что это кортеж из одного элемента, а не просто число в скобках. Для a2 это (2, 3): две строки и три столбца.
ndim — количество измерений, то есть длина кортежа shape. У a1 — 1, у a2 — 2. Это число совпадает с глубиной вложенности списков, которые вы передавали в np.array: плоский список → ndim=1, список списков → ndim=2.
size — общее количество элементов в массиве. Для a1: 3. Для a2: 2 × 3 = 6. Ключевое соотношение: size всегда равен произведению всех чисел из shape. Это не совпадение, а определение: форма массива однозначно задаёт количество его элементов.
print(a2.shape[0] * a2.shape[1]) # 6
print(a2.size) # 6 — одно и то же
dtype — тип данных всех элементов. Если нужен гарантированный тип вне зависимости от платформы — задайте его явно:
a_i64 = np.array([[1, 2, 3],
[4, 5, 6]], dtype=np.int64)
print(a_i64.dtype) # int64
print(a_i64.shape) # (2, 3)
a_f32 = np.array([[1, 2, 3],
[4, 5, 6]], dtype=np.float32)
print(a_f32.dtype) # float32
print(a_f32.shape) # (2, 3)
Меняется только тип хранения, но не структура. shape, ndim и size остаются теми же при любом dtype.
Четыре атрибута вместе дают полное описание структуры массива: shape говорит, как именно он устроен по измерениям; ndim — сколько таких измерений; size — сколько клеток в этой «сетке» всего; dtype — что лежит в каждой клетке. Эта четвёрка понадобится постоянно: когда будете проверять результат операции, передавать массив в функцию или отлаживать несовпадение размерностей.
Задача 1
Какой атрибут ndarray возвращает общее количество элементов в массиве?
Задача 2
Программист передаёт в np.array список [1, 2, 3] без явного dtype. Что верно про dtype результирующего массива?
Задача 3
Массив создан как arr = np.array([[10, 20], [30, 40]]). Чему равен arr.shape? Запишите ответ в виде кортежа Python.
Задача 4
Вывод dtype при смешанных числах: float-токены в двумерном массиве
Что уже дано
Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.
Что нужно сделать
Напишите программу, которая:
- Читает из
stdinдва целых числаrиc— количество строк и столбцов. - Читает следующие
rстрок; каждая содержит ровноcтокенов, разделённых пробелами. Каждый токен преобразуй черезfloat()— числа могут выглядеть как1,2.5,3.0и т.д. - Создаёт двумерный
ndarrayформы(r, c)с помощьюnp.arrayиз полученныхfloat-значений (без явногоdtype— NumPy выведет его автоматически). - Выводит в
stdoutодну строку:shape ndim size dtypeитогового массива.
Формат вывода shape — строго как у Python: (r, c).
Ввод и вывод
Программа читает stdin и пишет в stdout.
Формат ввода
r c токен_1_1 токен_1_2 ... токен_1_c ... токен_r_1 токен_r_2 ... токен_r_c
Первая строка — два целых числа r и c. Следующие r строк — по c токенов (каждый токен читается как float).
Формат вывода
Одна строка: shape ndim size dtype, например (2, 3) 2 6 float64.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 5
Явный dtype=float32: создание одномерного массива и вывод всех атрибутов
Что уже дано
Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.
Что нужно сделать
Напишите программу, которая:
- Читает из
stdinцелое числоn— количество элементов. - Читает следующую строку с
nцелыми числами, разделёнными пробелами. - Создаёт одномерный
ndarrayс помощьюnp.arrayиз прочитанных значений, явно передавdtype=np.float32. - Выводит в
stdoutчетыре значения через пробел:shape ndim size dtype, гдеdtype— строковое представление атрибута массива.
Формат shape — строго как у Python: (n,).
Ввод и вывод
Программа читает stdin и пишет в stdout.
Формат ввода
n элемент_1 элемент_2 ... элемент_n
Первая строка — целое число n. Вторая строка — n целых чисел через пробел.
Формат вывода
Одна строка: shape ndim size dtype, например (5,) 1 5 float32.
Обратите внимание: dtype в выводе должен быть именно float32, а не int64 или float64 — это прямое следствие явного dtype=np.float32.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 6
Диагностика dtype: целые против вещественных токенов в одномерном массиве
Что уже дано
Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.
Что нужно сделать
Напишите программу, которая:
- Читает из
stdinодну строку — метку режима: строго"int"или строго"float". - Читает вторую строку с
nтокенами, разделёнными пробелами. - Если метка равна
"int"— преобразует каждый токен черезint()и создаёт одномерныйndarrayчерезnp.arrayбез явногоdtype. - Если метка равна
"float"— преобразует каждый токен черезfloat()и создаёт одномерныйndarrayчерезnp.arrayбез явногоdtype. - Выводит в
stdoutодну строку:shape ndim size dtypeитогового массива.
Формат shape — строго как у Python: (n,).
Ввод и вывод
Программа читает stdin и пишет в stdout.
Формат ввода
метка токен_1 токен_2 ... токен_n
Первая строка — слово int или float. Вторая строка — n токенов через пробел. Гарантируется n ≥ 1.
Формат вывода
Одна строка: shape ndim size dtype, например (4,) 1 4 int64 или (4,) 1 4 float64.
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задача 7
Одинаковый size, разные формы: сравнение двух массивов
Что уже дано
Проверяющая система запускает вашу программу и подаёт данные через stdin. Никаких заранее созданных переменных нет — вы читаете всё сами.
Что нужно сделать
Напишите программу, которая:
- Читает из
stdinтри целых числа в одной строке:r,cиn. - Читает следующие
rстрок; каждая содержитcцелых чисел, разделённых пробелами. Из них создаёт двумерныйndarrayс помощьюnp.array. - Читает ещё одну строку с
nцелыми числами, разделёнными пробелами. Из них создаёт одномерныйndarrayс помощьюnp.array. - Гарантируется, что
r * c == n. - Выводит в
stdoutровно две строки:
- первая:
shape ndim size dtypeдля двумерного массива; - вторая:
shape ndim size dtypeдля одномерного массива.
Формат shape — строго как у Python: (r, c) или (n,).
Ввод и вывод
Программа читает stdin и пишет в stdout.
Формат ввода
r c n элемент_1_1 ... элемент_1_c ... элемент_r_1 ... элемент_r_c элемент_1 элемент_2 ... элемент_n
Первая строка — три целых числа r, c, n, где r * c == n. Следующие r строк — по c целых чисел. Последняя строка — n целых чисел.
Формат вывода
Две строки вида shape ndim size dtype, например:
(2, 3) 2 6 int64
(6,) 1 6 int64
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Задачи к уроку
- dtype NumPy: целые и вещественные массивы, типы элементов
Как NumPy выбирает dtype из int и float, что показывает dtype.kind и зачем задавать тип явно? Пример и задача с проверкой.
- NumPy shape, ndim, size и dtype: атрибуты массива и задача
Чем отличаются shape, ndim, size и dtype в NumPy? Короткий пример атрибутов ndarray и задача с проверкой кода без регистрации.
Продолжить с сохранением прогресса
Перейдите к уроку в учебном кабинете.
