Найти тему
Сам себе Data Scientist

Учим NumPy на практике. Часть 1

Оглавление

numpy.org

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

Здесь и приходит на помощь библиотека NumPy, которая отвечает за высоко оптимизированные многомерные массивы — основную структуру данных для большинства современных алгоритмов.

Разберём работу с NumPy на примере первых 15 задач из 100 задач, которые есть на Github. Данная коллекция представляет набор задач из numpy рассылки, вопросов StackOverflow и самой документации numpy, плюс дополненные задачи от автора.

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

Задача 1. Необходимо импортировать библиотеку под именем "np"

-2

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

Задача 2. Распечатать версию и конфигурацию numpy

-3

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

-4

Задача 3. Создать нулевой вектор длины 10 (вектор, заполненный нулями)

-5

Данная задача решается в одну строчку с помощью встроенного метода numpy.zeros(...). В приведённом выше решении будет создан вектор размерности 10, у которого все значения нули.

Если мы хотим создать матрицу с помощью numpy, то применяется следующий синтаксис:

-6

Данный код создаст матрицу, состоящую из нулей, размера 3 на 3.

Задача 4. Как найти размер памяти любого массива

Пусть у нас есть матрица 10 на 10:

-7

Для решения поставленной задачи воспользуемся двумя атрибутами.

1. Первый из них это numpy.ndarray.size.

-8

Данный атрибут отвечает за количество элементов в numpy-массиве. Так как у нас матрица 10 на 10, то количество элементов 100.

2. Следующий атрибут это numpy.dtype.itemsize.

Прежде чем разобрать этот атрибут, прежде всего необходимо знать, что у каждого элемента numpy-массива есть тип. Этот тип задаётся сразу при инициализации массива, либо библиотека задаст его по умолчанию, либо определит входные данные.

Например, при инициализации матрицы выше, мы могли указать тип явно:

-9

В данном примере мы указали, что значения являются вещественными. По умолчанию этот тип был задан в первом примере выше для данных. За это отвечает атрибут dtype. Подробнее о типах можно прочитать здесь.

Вернёмся к атрибуту itemsize. Он определяет сколько байт будет занимать в памяти каждый тип.

-10

Как видно, тип float64 у numpy занимает 8 байт 1 значение. Таким образом, получаем количество памяти, занимаемое нашей матрицей размера 10 на 10.

-11

Задача 5. Как получить документацию numpy-функции "add" из командной строки

Документацию каждой numpy-функции можно получить в командной строке следующим образом:

-12
python -c "import numpy; numpy.info(numpy.add)"

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

Задача 6. Создать нулевой вектор размером 10, но пятое значение которого равно 1

Это простая задача. Воспользуемся уже знакомым методом numpy.zeros(...) и заменим пятое значение вектора на 1. Так как нумерация начинается с 0, то пятый будет под индексом 4

-13

Задача 7. Создать вектор с последовательными значениями в диапазоне от 10 до 49

Для решения этой задачи используется встроенный метод numpy.arange.

-14

Задача 8. Перевернуть (reverse) вектор (первый элемент становится последним)

В данной задаче необходимо сделать вектор в обратном порядке. Чтобы видно было результат, воспользуемся функцией генерации последовательных чисел вектора numpy.arange.

-15

О двойном двоеточии можно прочитать статью на Хабре в разделе "Срезы".

Задача 9. создайте матрицу 3х3 с последовательными значениями в диапазоне от 0 до 8

То есть нужно получить вот такую матрицу

-16

Когда мы создаём массив в numpy, у каждого массива есть атрибут shape (форма), который говорит, какого вида у нас массив: вектор, матрица и т.д.

Например, для вектора атрибут shape выглядит следующим образом:

-17

В NumPy есть встроенная функция, которая позволяет преобразовать numpy-массив в другую форму (shape): numpy.reshape. Рассмотрим сразу на решении поставленной задачи:

-18

Мы создали одномерный вектор из последовательно идущих цифр от 0 до 8. Изначально этот вектор имел форму (9, ). Но после мы преобразовали форму в матрицу 3х3.

Не сложно убедиться, что форма массива стала другой

-19

Задача 10. Найти индексы ненулевых элементов из [1,2,0,0,4,0]

Для этого есть встроенная функция np.nonzero, которая возвращает список индексов ненулевых элементов:

-20

Кстати, за счёт встроенного механизма индексирования в numpy-массивах, можно получить все ненулевые элементы массива:

-21

Задача 11. Создать единичную матрицу размера 3х3

Для этого есть встроенная функция numpy.eye:

-22

Задача 12. Создать массив 3x3x3 со случайными значениями

Здесь используется функция функция numpy.random.random:

-23

Как видно для указания размера массива нужно передать tuple. Данный метод заполняет массив значениями из интервала [0.0, 1.0).

Задача 13. Создать массив 10х10 со случайными значениями и найти минимальное и максимальное значения

Сначала создадим массив с уже знакомой нам функцией:

-24

Далее используем встроенные функции min и max, чтобы найти соответствующие значения:

-25

Задача 14. Создать случайный вектор размером 30 и найти среднее значение

Для тех, кто забыл. Среднее значение вектора — это сумма всех его элементов, делённое на их количество:

-26

Для вычисления среднего значения массив используется встроенная функция mean:

-27

Задача 15. Создать двумерный массив с 1 на границе и 0 внутри

Для начала посмотрим решение:

-28

Первым делом здесь создаётся массив, заполненный единицами с помощью метода numpy.ones.

Теперь про заполнение нулями. Прежде всего напомним, что индексация массива начинается с нуля. Поэтому вторая строка имеет индекс 1.

При обращении Z[1:-1, ...] мы говорим брать строки со второй и до предпоследней (-1 значит с конца).

Z[..., 1:-1] — наоборот указываем столбцы со второго и до предпоследнего.

Z[1:-1, 1:-1] — Таким образом получим весь внутренний срез матрицы, не включающий границы. Подробнее про срезы в numpy-массивах можно прочитать в этой статье.

На этом всё :) Остальные задачи рассмотрим в следующих частях.

Ставьте лайк, если статья понравилась и подписывайтесь на канал. Впереди ещё много интересного!