Массив Numpy | Программирование на Питоне

Массив Numpy

Все курсы > Программирование на Питоне > Занятие 9

массив Numpy

Первое знакомство с библиотекой NumPy (Numerical Python) состоялось на двенадцатом занятии вводного курса. Затем мы несколько раз использовали эту библиотеку при построении моделей. Пришло время посвятить ее функционалу отдельный раздел.

Библиотека Numpy является основой для многих других библиотек в Питоне, например, Pandas, Matplotlib, scikit-learn или scikit-image. Главный объект библиотеки — массив Numpy (Numpy array). О нем мы поговорим сегодня.

На следующем занятии мы изучим математические операции над массивами, а через одно — рассмотрим работу со случайными числами.

Содержание занятия

Понятие массива Numpy

Массив Numpy — это многомерный массив (ndarray, n-dimensional array) данных, над которыми можно быстро и эффективно выполнять множество математических, статистических, логических и других операций.

Приведу пример массива с нулевым измерением, а также одно-, двух- и трехмерного массивов.

пример массива Numpy с нулевым измерением, а также одно-, двух- и трехмерного массивов.

Теперь посмотрим как работать с этими массивами на практике.

Откроем ноутбук к этому занятию

Вначале нужно импортировать библиотеку Numpy.

Как создать массив Numpy

Рассмотрим два варианта создания одномерного массива.

Функция np.array()

Во-первых, массив можно создать с помощью функции np.array(), которой мы передаем, например, список или кортеж элементов.

Функция np.arange()

Кроме того, можно воспользоваться функцией np.arange(). Эта функция, как и функция range(), с которой мы уже знакомы, создает последовательность элементов. Обязательным параметром является верхняя граница, которая не входит в последовательность.

Нижняя граница и шаг обязательными не являются.

Отличие range() от функции np.arange() заключается в том, что первая не допускает использования типа float.

ошибка: значение типа float в списке

При этом в массиве Numpy тип float вполне может использоваться.

Тип данных элементов массива

Как вы уже вероятно обратили внимание, в массивах тип данных определяется автоматически. При этом при создании массива мы можем задать этот параметр принудительно.

Обратите внимание, в отличие, например, от списков, чаще всего в массивах содержатся элементы только одного типа (в частности, int или float).

Свойства (атрибуты) массива

Возьмем массив, который мы создали выше.

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

Теперь, с помощью атрибута shape, посмотрим на количество элементов в каждом измерении.

Обратите внимание, даже когда массив одномерный, результат атрибута shape выводится в виде кортежа (на это указывают круглые скобки и запятая после цифры четыре).

Атрибут size показывает общее количество элементов во всех измерениях.

Как уже было сказано выше, атрибут dtype показывает тип данных отдельного элемента.

Атрибут itemsize позволяет узнать размер в байтах (один байт состоит из 8 бит) одного элемента. В нашем случае, элемент (число) состоит из 64 бит, что составляет восемь байтов.

Общий размер массива в байтах (nbytes) позволяет понять, в частности, поместится ли массив в оперативную память компьютера.

Тот же результат можно получить, умножив общее количество элементов на размер одного элемента в байтах.

Измерения массива

Как уже было сказано, ndarray (массив Numpy) — это многомерный массив. Давайте еще раз взглянем на массивы с различными измерениями, добавив только что изученные атрибуты этих массивов.

нулевой массив, одно-, двух- и трехмерный массивы и их атрибуты

Теперь подробнее поговорим про размерность. Измерения (dimensions) создаются за счёт вложения одного массива в другой с помощью квадратных скобок []. Начнем с массива с нулевой размерностью.

Массив с нулевой размерностью

Массив с нулевой размерностью — это число (скаляр) и квадратных скобок не имеет.

Посмотрим на свойства этого массива.

Атрибут shape показывает отсутствие размерности, а size указывает на один элемент в массиве.

Одномерный массив (вектор)

Вложив несколько массивов с нулевой размерностью в квадратные скобки, мы получим одномерный массив или вектор.

Снова воспользуемся атрибутами массива.

Двумерный массив (матрица)

Поместив во вторые квадратные скобки, например, два одномерных массива, мы получим двумерный массив или матрицу.

Посмотрим на свойства.

Атрибут size двумерного массива более интуитивно понятен. В данном случае два элемента одного измерения умножены на три элемента второго.

Добавлю, что с точки зрения Numpy матрица с одной строкой или одним столбцом — это разные объекты. Начнем с матрицы, которая имеет три вектора по одному элементу.

Теперь наоборот, создадим матрицу с одной строкой, в которой три элемента.

Трехмерный массив

Теперь создадим трехмерный массив, внутри которого будут два двумерных массива 2 х 3. Общее количество элементов будет равно двенадцати (2 х 2 х 3). Визуально это можно представить как стэк (наложение) двух матриц.

пример трехмерного массива и атрибут shape

При этом, вместо того чтобы вручную прописывать все 12 значений, мы последовательно воспользуемся функцией np.arange() и методом np.reshape().

Функция np.arange(), как мы уже видели выше, создаст одномерный массив из 12 элементов, а метод np.reshape() распределит их по измерениям. Выведем атрибуты.

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

Аналогичным образом создаются четырехмерные массивы, а также массивы с большим количеством измерений.

Понятие тензора

Добавлю, что в математике n-мерный массив называется тензором, а числа (скаляры), векторы и матрицы являются его частными случаями для нуля, одного и двух измерений соответственно.

виды тензоров: скаляр, вектор, матрица

Другие способы создания массива

Массив из нулей

Иногда бывает полезно создать массив, все элементы которого равны нулю. Для этого используется функция np.zeros().

Массив из единиц

В тех случаях когда нужно создать массив, заполненный единицами, можно воспользоваться функцией np.ones().

Массив, заполненный заданным значением

Функция np.full() создает массив, заполненный заданным значением.

Пустой массив Numpy

В отличие от предыдущих инструментов, функция np.empty() возвращает массив заданной размерности, но без инициализации его значений. Другими словами, пустой массив.

Кроме того, любой массив Numpy можно преобразовать в описанные выше массивы с помощью функций np.zeros_like(), np.ones_like(), np.full_like() и np.empty_like(). Приведу пример для np.zeros_like().

Примеры работы с тремя оставшимися функциями можно посмотреть в ноутбуке⧉.

Функция np.linspace()

Функция np.linspace() позволяет указать диапазон начального и конечного значений, а также количество равноудаленных точек внутри этого диапазона (включая начальное и конечное значения).

Обратите внимание, функция np.linspace() сама определяет, где расставить точки. Нам нужно лишь указать их количество. Этим она отличается от функции np.arange(), в которой мы указываем шаг в пределах заданного диапазона.

Функцию np.linspace() удобно использовать для построения графиков функций.

парабола, созданная с помощью функции np.linspace()

В качестве примера выведем первые 10 точек, созданные функцией np.linspace().

Функции np.random.rand() и np.random.randint()

Массивы можно также создавать с помощью функций, генерирующих псевдослучайные числа. В частности, функция np.random.rand() создает массив заданной размерности, заполненный числами от 0 до 1 (единица в диапазон не входит).

Функция np.random.randint() формирует массив целых чисел в заданном диапазоне (верхняя граница не входит в диапазон) и с заданной размерностью.

Более подробно с этими и другими похожими функциями мы познакомимся на одиннадцатом занятии.

Создание массива из функции

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

координаты элементов массива Numpy

Функция np.fromfunction() берет координаты (i, j) каждой ячейки и передает их в собственную функцию. Посмотрим, как это работает на практике.

Теперь применим эту функцию к каждой ячейке (координатам) массива с размерностью (3, 3).

В np.fromfunction() можно передать и lambda-функцию.

Матрица csr и метод .toarray()

Кроме этого в случае если данные хранятся в формате csr (сжатое хранения строкой, compressed sparse row), то мы можем преобразовать их обратно в массив Numpy с помощью метода .toarray().

Долю нулевых значений несложно посчитать через функцию np.count_nonzero() и атрибут size.

Преобразуем матрицу в формат csr.

Вернем матрицу csr обратно в формат массива Numpy.

Напомню, что с форматом csr мы впервые познакомились, когда изучали рекомендательные системы. Метод .toarray() мы активно применяли на занятии по обработке естественного языка.

Индексы и срезы

Индекс элемента массива

Подобно спискам, к элементам массива можно получить доступ по их индексу. Главное отличие — необходимо учитывать наличие измерений. Вначале рассмотрим индексы массива на схеме.

двумерный массив и индекс его элементов

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

Другими словами, мы двигаемся как бы снаружи вовнутрь, перемещаясь из одного измерения в другое.

Посмотрим, как это реализовать на Питоне. Создадим двумерный массив.

Посмотрим на измерения и количество элементов в каждом из них.

Выведем первый элемент первого (внешнего) измерения.

Второй индекс позволяет обратиться, например, к первому элементу первого вектора.

Теперь выведем значение шесть.

Срез массива

В массиве Numpy доступны и срезы (slice). Срез одномерного массива очень похож на срез списка.

Возьмем каждый второй элемент в интервале с 1-го по 6-й индекс.

Посмотрим на схему.

срез массива Numpy

Когда измерений больше одного, внутри квадратных скобок измерения отделяются запятой. Создадим двумерный массив.

Сделаем срез из первой строки (внешнее измерение) и первых двух столбцов (внутреннее измерение).

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

С помощью среза можно вывести конкретный элемент массива.

Другими словами, c[0, 0] == c [0][0].

Кроме того, обратите внимание, что индекс в формате array[i, j] и координаты элементов массива, которые мы рассмотрели ранее, это одно и то же.

Допускаются срезы с отрицательным индексом.

Рассмотрим более сложный пример. Возьмем всю вторую строку [1] и каждый второй столбец [::2].

Теперь создадим массив с тремя измерениями.

Можно сказать, что наш 3D массив состоит из четырех матриц 2 x 2.

Вначале выведем значение десять. Если идти снаружи вовнутрь, получается, что это третья матрица [2], второй вектор [1] и первый элемент [0].

Для срезов понадобится две запятых.

Если указать только один срез, мы будем работать только во внешнем измерении (с четырьмя матрицами).

Прежде чем завершить разговор про срезы, выведем первые строки каждой матрицы.

Оси массива

С концепцией измерения массива тесно связано понятие оси (axis, множественное число — axes). У массива столько же осей, сколько и измерений. Мы уже столкнулись с осями двух и трехмерного массивов, когда работали с изображениями.

Рассмотрим этот вопрос ещё раз.

Массив 2D

В двумерном массиве два измерения и соответственно две оси.

оси двумерного массива

В документации Numpy существует такое понятие как первая и последняя ось. Применительно к двумерному массиву, ось 0 — это первая ось, а ось 1 — последняя.

Многие, в частности, математические и статистические методы в Numpy предполагают указание параметра оси. Продолжим работу с приведенным выше двумерным массивом.

Сложение вдоль первой оси (axis = 0)

Найдем сумму по столбцам (вдоль оси 0).

сложение элементов двумерного массива вдоль оси 0

Сложение вдоль второй оси (axis = 1)

Теперь найдем сумму по строкам (вдоль оси 1).

сложение элементов двумерного массива вдоль оси 1

Обратите внимание, хотя axis = 0 принято ассоциировать со строками двумерного массива, сложение происходит вдоль вертикальной оси или по столбцам. Параметр axis = 1, отвечающий за столбцы, наоборот предполагает сложение вдоль горизонтальной оси по строкам.

При таких операциях говорят, что мы агрегируем (aggregate) данные и сворачиваем (collapse) или сокращаем (reduce) измерения вдоль определенной оси. И действительно, в каждой из описанных выше операций двумерный массив превратился в одномерный.

Сложение вдоль обеих осей (axis = (0, 1))

Если в параметр axis передать кортеж с указанием обеих осей (0, 1), сумма будет рассчитана сначала вдоль оси 0, затем вдоль оси 1.

сложение элементов двумерного массива вдоль осей 0 и 1

Если параметр axis не указывать, сумма также будет рассчитана по всем элементам массива.

В этом случае «под капотом» стоит значение по умолчанию axis = None.

Отрицательные значения в параметре axis

Массив Numpy допускает отрицательное значение параметра axis. Параметр axis = −1 соответствует последней по счету оси, то есть оси 1.

Сложение вдоль оси 0 соответствует параметру axis = −2.

Массив 3D

Расположение осей трехмерного массива не всегда бывает очевидным.

Как уже было сказано, оси тесно связаны с измерениями и понять какая ось первая, какая вторая, а какая третья проще всего через атрибут shape. Вновь рассмотрим приведенный выше трехмерный массив.

оси трехмерного массива

Как мы видим, первая ось (axis = 0) в параметре shape всегда стоит на первом месте.

Сложение вдоль первой оси (axis = 0)

Применим функцию np.sum() с параметром axis = 0.

Визуально это можно представить как поэлементное сложение двух матриц.

сложение элементов трехмерного массива вдоль оси 0

Если использовать индексы массива, то поэлементное сложение вдоль оси 0 можно реализовать следующим образом.

Эту же задачу можно решить с помощью цикла for. Вначале нам нужно создать нулевую матрицу, размерность которой будет соответствовать желаемому результату сложения вдоль оси 0.

Теперь создадим цикл for с двумя итерациями (потому что мы складываем две матрицы внутри трехмерного массива) через функцию range() с параметром 2.

Внутри цикла мы на первой итерации (i равно 0) запишем в нулевой массив нашу первую матрицу, а на второй итерации (i равно 1) поэлементно прибавим вторую. Переменная i в данном случае стала индексом для массива arr_3D.

Мы применили цикл for к массиву Numpy исключительно в учебных целях. На практике этого стоит избегать. Встроенные функции Numpy исполняются гораздо быстрее.

Сложение вдоль второй оси (axis = 1)

Теперь посмотрим на сложение с параметром axis = 1.

Сложение вдоль оси 1 предполагает, что мы складываем столбцы каждой матрицы.

сложение элементов трехмерного массива вдоль оси 1

Посмотрим на сложение через индексы.

Теперь, опять же в учебных целях, решим эту задачу через цикл for.

Сложение вдоль третьей оси (axis = 2)

Сложение вдоль оси 2 предполагает, что мы складываем строки каждой матрицы.

сложение элементов трехмерного массива вдоль оси 2

Покажем сложение строк через индексы для первой строки первой матрицы [0, 1, 2].

Сложение каждой строки можно посмотреть в ноутбуке⧉. Теперь применим цикл for.

Сложение вдоль первой и второй осей (axis = (0, 1))

Здесь мы объединили две операции сложения вначале вдоль оси 0, затем вдоль оси 1. Схемы этих операций можно посмотреть выше.

В цикле for этот алгоритм можно реализовать либо (1) через два отдельных цикла, либо (2) через вложенные друг в друга циклы. При использовании двух циклов (1) мы вначале складываем матрицы.

На втором этапе мы складываем столбцы предыдущего результата.

При использовании вложенных циклов (2) мы пройдемся по строкам каждой матрицы и поэлементно сложим их (т.е. произведем сложение по столбцам).

Сложение вдоль всех трех осей (axis = (0, 1, 2))

При сложении вдоль всех трех осей мы можем указать каждую ось в параметре axis.

Кроме того, аналогично двумерному массиву, если параметр axis не указывать, сложение также будет произведено по всем измерениям.

Реализация алгоритма через цикл for в данном случае достаточно проста.

В целом, результатом сложения по всем измерениям для массива любой размерности будет скаляр (число).

Обратите внимание, при работе с трехмерным массивом также происходит агрегирование данных и сокращение измерений. Исчезает та ось или измерение, вдоль которого осуществлялось сложение.

Напоследок замечу, что мы использовали функцию np.sum() в большей степени для иллюстриции операций вдоль определенной оси. Математические возможности Numpy будут рассмотрены на следующем занятии.

Операции с массивами

Функция len()

Вновь возьмем трехмерный массив.

По умолчанию функция len() выводит длину внешнего измерения (ось 0). Это внешние скобки, в которых содержатся две матрицы 2 x 3.

Для того чтобы вывести, например, длину внутреннего измерения, т.е. вектора из трех элементов (ось 1), нужно воспользоваться индексом.

Вхождение элемента в массив

Проверим, входит ли значение 3 в созданный выше массив arr_3D.

Теперь проверим, не входит ли значение 11.

Распаковка массива

Возьмем матрицу из трех строк и девяти столбцов.

Во внешнем измерении (ось 0) три элемента. Мы можем распаковать (unpack) их в три переменные.

Выведем первую переменную (строку).

Теперь распакуем первый, последний и остальные элементы первой строки в отдельные переменные.

Выведем каждую переменную.

С таким способом распаковки мы познакомились, когда говорили про списки.

Изменение элементов массива

Обратимся к двумерному массиву.

Заменим первый элемент первой строки по его индексу.

Запишем значение 1 в первую строку.

Пусть третий столбец массива состоит из нулей.

Теперь потренируемся с трехмерным массивом.

Выберем второй столбец второй матрицы и заменим значения столбца 7 и 10 на 0 и 1.

Заменим все элементы массива на число семь с помощью метода .fill().

Сортировка массива и обратный порядок его элементов

Функция np.sort()

Возьмем двумерный массив.

Как и во многих других функциях главное разобраться с применением параметра axis. По умолчанию сортировка идет с параметром axis = −1 (последняя ось).

Для двумерного массива это ось 1.

Теперь посмотрим на сортировку по оси 0.

Параметр axis = None вначале возвращает одномерный массив, а затем сортирует его.

Обратный порядок элементов массива

Для того чтобы задать обратный порядок элементов, можно использовать оператор среза с параметром шага −1.

Обратный порядок элементов можно совмещать со срезами.

Теперь возьмем двумерный массив.

С помощью оператора среза можно задать обратный порядок по двум измерениям.

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

Помимо этого, обратный порядок можно задать через функцию np.flip(). По умолчанию эта функцию задает обратный порядок по двум измерениям.

Отдельно можно задать порядок по внешнему и внутреннему измерениям.

Сортировка в убывающем порядке

Возможно вы обратили внимание, что при использовании функции np.sort() мы сортировали элементы только в возрастающем порядке. По другому она не умеет. Для того чтобы отсортировать элементы в убывающем порядке можно воспользоваться оператором среза.

Одновременно применим функцию np.sort() и оператор среза с параметром шага −1.

Обращу ваше внимание, что исходный массив не изменился.

При этом можно воспользоваться и методом .sort().

Изменится исходный массив.

Изменение размерности

Метод .reshape()

Возьмем простой трехмерный массив.

С помощью метода .reshape() мы можем изменить количество измерений. Например, мы можем превратить этот массив в матрицу с размерностью 2 x 6.

Функция np.resize() и метод .resize()

С другой стороны, если мы хотим не только задать другую размерность, но и изменить общее количество элементов, то мы можем воспользоваться функцией np.resize() и методом .resize().

Перед тем как воспользоваться методом .resize() нам необходимо создать копию массива arr_2D. Все дело в том, что переменная arr_2D ссылается на другой массив (в частности, на трехмерный массив arr_3D), а метод .resize() может работать только с исходным массивом.

Метод .resize() также создаст отдельную копию, изменит размерность и заполнит пропуски нулями.

Методы .flatten() и .ravel()

Метод .flatten() переводит («вытягивает») массив в одно измерение и создает копию исходного массива (как метод .copy()).

Напомню, что концепцию вытягивания массива мы использовали при работе с изображениями на занятиях по компьютерному зрению и основам нейронных сетей.

Метод .ravel() делает то же самое, но не создает копию исходного массива и за счет этого быстрее, чем .flatten().

Метод .ravel() мы использовали на занятии по обработке естественного языка.

np.newaxis

Объект np.newaxis добавляет измерение в уже существующем массиве.

Мы можем добавить в этот массив новое первое измерение и, таким образом, сделать существующее измерение вторым.

Аналогично, мы можем добавить новое второе измерение, а существующее измерение оставить первым.

Функция np.expand_dims()

Функция np.expand_dims() добавляет измерение, указанное в параметре axis. Возьмем двумерный массив.

Добавим внешнее измерение.

Теперь добавим измерение «по середине».

А также внутреннее измерение.

Функция np.squeeze()

Возьмем массив 4D, в котором первое и последнее измерения содержат по одному элементу.

Удалим эти измерения с помощью функции np.squeeze().

Новый массив имеет только два измерения.

Этот метод мы использовали при создании рекомендательной системы.

Объединение массивов

Функция np.concatenate()

Предположим, что у нас есть два квардратных массива a и b размерностью 2 x 2.

Объединим массивы вдоль оси 0 без добавления нового измерения.

Точно так же массивы можно объединить вдоль оси 1.

Функция np.stack()

Отличие функции np.stack() от np.concatenate() в том, что при объединении массивов мы добавляем новое измерение (новую ось).

Несколько более сложным оказывается поведение при axis = 1 и axis = 2.

Фильтр (маска) массива

Задача фильтрации массива (или как еще говорят создания маски массива) встречается довольно часто. К примеру, предположим, что мы собрали показания прибора, однако из-за ошибки датчика часть из них оказалась некорректной, и для последующего анализа эти значения нужно удалить.

Логическая маска (Boolean mask)

Пусть дан массив Numpy, и мы хотим удалить из него отрицательные значения.

Для того чтобы создать фильтр массива достаточно указать критерий отбора. На выходе мы получим массив из логических значений True и False, в котором нежелательные значения будут помечены как False.

Применим маску к исходному массиву.

Кроме того, отфильтрованные значения можно заполнить, например, нулями.

Отдельно отмечу, что удаление или заполнение нулями некачественно собранных данных далеко не всегда является оптимальной стратегией. Более подробно мы поговорим об этом на курсе анализа и обработки данных.

Пороговое преобразование изображения

Еще одним примером использования фильтра массива является так называемое пороговое преобразование. Его мы изучали на занятии по компьютерному зрению. Рассмотрим этот код еще раз.

Каждый пиксель изображения с оттенками серого (grayscale image), напомню, представляет собой значение в диапазоне от 0 до 255. Мы можем задать некоторый порог, пусть это будет число 87, и все значения выше этого порога сделать True или единицей, а ниже — False или нулем. Далее, если преобразовать единицы и нули в белый и черный цвета соответственно, то на выходе мы получим черно-белое изображение (binary image), в котором передний и задний планы разделены.

Подобный массив из значений False и True есть не что иное как маска исходного массива.

Посмотрим на значения исходного массива.

И на значения его маски.

Остается визуально оценить результат.

пороговое преобразование с помощью маски массива Numpy

Masked array

Альтернативный способ фильтрации массива Numpy предполагает использование модуля ma (masked array).

В отличие от описанного выше логического фильтра, в masked array опускаются элементы, помеченные как 1 или True.

Обратите внимание, нежелательные значения не исчезают полностью, а заполняются --.

Кроме того, для некоторых логических условий есть отдельные функции. Например, мы можем опустить все элементы меньше определенного значения.

Рассмотрим еще одну возможность модуля ma. Возьмем массив, в котором есть пропущенные значения (NaN, Not a Number) и значение бесконечности (inf, infinity).

Если мы попробуем посчитать сумму этих значений, результатом будет пропущенное значение.

Для решения этой проблемы мы можем применить функцию masked_invalid(). Она автоматически отфильтровывает пропущенные значения и значения бесконечности.

Теперь мы можем без труда сложить оставшиеся элементы.

Более того, с помощью метода .filled() мы можем заполнить образовавшиеся пропуски. Например, средним арифметическим оставшихся элементов.

Прежде чем завершить, рассмотрим еще одну дополнительную тему, а именно вызов справки непосредственно в Google Colab.

Документация

Справку по функции можно вызвать с помощью знака вопроса. Документация появится в отдельном окне.

Обратите внимание, мы не использовали круглых скобок.

Кроме того, можно применить функцию help(). В этом случае документация появится под вызываемой функцией.

С помощью функции np.lookfor() мы можем осуществить поиск непосредственно по документации Numpy.

Подведем итог

На сегодняшнем занятии мы достаточно подробно рассмотрели массив Numpy. В частности, мы узнали о том, как создавать массив, какие у него есть атрибуты и как реализована многомерность массива. Мы изучили индексы и оси, а также поговорили про основные операции с массивами.

Вопросы для закрепления

Вопрос. Как выяснить очередность осей массива?

Посмотреть правильный ответ

Вопрос. Что происходит с осью (измерением), вдоль которой происходит сложение элементов массива?

Посмотреть правильный ответ

Вопрос. Как отсортировать массив в убывающем порядке?

Посмотреть правильный ответ

В ноутбуке к лекции приведены дополнительные упражнения⧉.

На следующем занятии мы сделаем акцент на математических и статистических возможностях библиотеки Numpy.