- 4. Создание массивов
- 3. Массивы NumPy
- 3.1. Прежде чем читать
- 3.2. Основы
- 3.3. Напоследок
- Изучение NumPy с визуальными примерами для начинающих
- Содержание
- Создание массивов NumPy
- Арифметические операции над массивами NumPy
- Индексация массива NumPy
- Агрегирование в NumPy
- Использование нескольких размерностей NumPy
- Создание матриц NumPy на примерах
- Арифметические операции над матрицами NumPy
- dot() Скалярное произведение NumPy
- Индексация матрицы NumPy
- Агрегирование матриц NumPy
- Транспонирование и изменение формы матриц в numpy
- Еще больше размерностей NumPy
- Примеры работы с NumPy
- Математические формулы NumPy
- Представление данных NumPy
- Таблицы NumPy — примеры использования таблиц
- Аудио и временные ряды в NumPy
- Обработка изображений в NumPy
- Обработка текста в NumPy на примерах
4. Создание массивов
Данная глава является лишь кратким обзором, поскольку способов создания массивов очень много, их описание и примеры использования вы найдете в разделе «Создание массивов» справочного руководства.
И так, массив может быть создан из обычного списка или кортежа Python с использованием функции array() . Причем тип полученного массива зависит от типа элементов последовательности:
Необходимо помнить о том, что аргументом функции array() должна быть именно последовательность, а не несколько аргументов.
Функция array() преобразует последовательности последовательностей в двумерные массивы, а последовательности последовательностей, которые тоже состоят из последовательностей в трехмерные массивы. То есть уровень вложенности исходной последовательности определяет размерность получаемого массива:
Функция array() так же позволяет определить тип данных массива.
Очень часто возникает задача создания массива определенного размера, причем чем заполнен массив абсолютно неважно. В этом случае можно воспользоваться циклами или генераторами списков (кортежей), но NumPy для таких случаев предлагает более быстрые и менее затратные функции-заполнители.
Функция zeros заполняет массив нулями, функция ones — единицами, а функция empty — случайными числами, которые зависят от состояния памяти. По умолчанию, тип создаваемого массива — float64.
Для создания последовательностей чисел NumPy предоставляет функцию arange , которая возвращает одномерные массивы:
Если функция arange используется с аргументами типа float, то предсказать количество элементов в возвращаемом массиве не так-то просто. Гораздо чаще возникает необходимость указания не шага изменения чисел в диапазоне, а количества чисел в заданном диапазоне. Функция linspace , так же как и arange принимает три аргумента, но третий аргумент, как раз и указывает количество чисел в диапазоне.
Функция linspace удобна еще и тем, что может быть использована для вычисления значений функций на заданном множестве точек:
Источник
3. Массивы NumPy
3.1. Прежде чем читать
Нужно немного знать Python. Причем «немного» означает действительно немного и вовсе не означает, что перед чтением данного руководства вам нужно досконально изучить этот язык. Открытой вкладки с официальным руководством окажется вполне достаточно.
Все примеры выполнены в консоли IDE Spyder дистрибутива Anaconda на Python версии 3.5. и NumPy версии 1.14.0. Приводимые примеры так же будут работать в любом другом дистрибутиве Python 3.х версии и последней версией пакета NumPy. Но если некоторые примеры все же не работают, то ознакомьтесь с официальной документацией вашего дистрибутива, возможно причина связана с его особенностями.
Например, если в своем дистрибутиве вы обнаружили последнюю версию IDE Spyder, то в ней нет Python консоли, к которой привыкают многие новички, учившиеся экспериментировать с кодом в IDLE. При этом новичкам может так же показаться, что и все примеры, представленные здесь, тоже лучше выполнять в Python консоли. Но нет, Python консоль использовалась автором лишь по техническим причинам, которые связаны с редактурой, версткой и дизайном кода. Консоль IPython имеет гораздо больше преимуществ.
3.2. Основы
Главный объект NumPy — это однородный многомерный массив. Чаще всего это одномерная последовательность или двумерная таблица, заполненные элементами одного типа, как правило числами, которые проиндексированы кортежем положительных целых чисел. В NumPy, элементы этого кортежа называются осями, а число осей рангом.
Что бы перейти к примерам, сначала выполним импорт пакета:
Импортирование numpy под псевдонимом np уже стало общепринятой, негласной, договоренностью, можно сказать, традицией.
Теперь мы може приступить к примерам. Способов создания массивов NumPy довольно много, но мы начнем с самого тривиального — создание массива из заполненного вручную списка Python:
Теперь у нас есть одномерный массив (словосочетание «ранг массива» вряд ли приживется в русском языке), т.е. у него всего одна ось вдоль которой происходит индексирование его элементов.
Получить доступ к числу 33 можно привычным способом:
В общем-то, можно подумать, что ничего интересного и нет в этих массивах, но на самом деле это только начало кроличьей норы. Оцените:
Вместо одного индекса, указан целый список индексов. А вот еще любопытный пример, теперь вместо индекса укажем логическое выражение:
Цель этих двух примеров — не устраивать головоломку, а продемонстрировать расширенные возможности индексирования массивов NumPy. С тем как устроена индексация мы разберемся в другой главе. Что еще интересного можно продемонстрировать? Векторизованные вычисления:
Векторизованные — означает, что все арифметические операции и математические функции выполняются сразу над всеми элементами массивов. А это в свою очередь означает, что нет никакой необходимости выполнять вычисления в цикле. В случае одномерного массива, можно подумать, что это не такой уж бонус, ведь есть генераторы. Но давайте перейдем к двумерным массивам:
Сейчас мы создали массив с помощью функции np.arange() , которая во многом аналогична функции range() языка Python. Затем, мы изменили форму массива с помощью метода reshape() , т.е. на самом деле создать этот массив мы могли бы и одной командой:
Визуально, данный массив выглядит следующим образом:
Глядя на картинку, становится понятно, что первая ось (и индекс соответственно) — это строки, вторая ось — это столбцы. Т.е. получить элемент 9 можно простой командой:
Снова можно подумать, что ничего нового — все как в Python. Да, так и есть, и, это круто! Еще круто, то что NumPy добавляет к удобному и привычному синтаксису Python, весьма удобные трюки, например — транслирование массивов:
В данном примере, без всяких циклов (и генераторов), мы умножили каждый столбец из массива a на соответствующий элемент из массива b . Т.е. мы как бы транслировали (в какой-то степени можно сказать — растянули) массив b по массиву a .
То же самое мы можем проделать с каждой строкой массива a :
В данном случае мы просто прибавили к массиву a массив-столбец c . И получили, то что хотели. Сейчас мы не будем подробно рассматривать механизм транслирования — это тема другой главы. Вместо этого я хочу отметить, что при работе с двумерными или трехмерными массивами, особенно с массивами большей размерности, становится очень важным удобство работы с элементами массива, которые расположены вдоль отдельных измерений — его осей.
Например, у нас есть двумерный массив и мы хотим узнать его минимальные элементы по строкам и столбцам. Для начала создадим массив из случайных чисел и пусть, для нашего удобства, эти числа будут целыми:
Минимальный элемент в данном массиве это:
А вот минимальные элементы по столбцам и строкам:
Такое поведение заложено практически во все функции и методы NumPy:
Чтож, мы рассмотрели одномерные и двумерные массивы, а так же некоторые трюки NumPy. Но данный пакет позиционируется прежде всего как научный инструмент. Что насчет вычислений, их скорости и занимаемой памяти?
Для примера, создадим трехмерный массив:
Почему именно трехмерный? На самом деле реальный мир вовсе не ограничивается таблицами, векторами и матрицами. Еще существуют тензоры, кватернионы, октавы. А некоторые данные, гораздо удобнее представлять именно в трехмерном и четырехмерном представлении, например, биржевые торги по всем инструментам, лучше всего представлять в трехмерном виде, а торги нескольких бирж в четырехмерном. Конечно, такими сложными вычислениями занимается очень небольшое количество людей, но надо отметить, что именно эти люди двигают науку и индустрию вперед. Да и слово «сложное» можно считать синонимом «интересное. Поэтому. что-то мы отвлеклись. вот наш трехмерный массив:
Визуализация (и хорошее воображение) позволяет сразу догадаться, как устроена индексация трехмерных массивов. Например, если нам нужно вытащить из данного массива число 31, то достаточно выполнить:
Но, что если мы хотим узнать побольше об этом массиве. В самом деле, у массивов есть целый ряд важных атрибутов. Например, количество осей массива (его размерность), которую при работе с очень большими массивами, не всегда легко увидеть:
Массив a действительно трехмерный. Но иногда становится интересно, а на сколько же большой массив перед нами. Например, какой он формы, т.е. сколько элементов расположено вдоль каждой оси? Ответить позволяет метод ndarray.shape :
Метод ndarray.size просто возвращает общее количество элементов массива:
Еще может встать такой вопрос — сколько памяти занимает наш массив? Иногда даже возникает такой вопрос — влезет ли результирующий массив после всех вычислений в оперативную память? Что бы на него ответить надо знать, сколько «весит» один элемент массива:
ndarray.itemsize возвращает размер элемента в байтах. Теперь мы можем узнать сколько «весит» наш массив:
Итого — 192 байта. На самом деле, размер занимаемой массивом памяти, зависит не только от количества элементов в нем, но и от испльзуемого типа данных:
dtype(‘int32’) — означает, что используется целочисленный тип данных, в котором для хранения одного числа выделяется 32 бита памяти. Но если мы выполним какие-нибудь вычисления с массивом, то тип данных может измениться:
Теперь у нас есть еще один массив — массив b и его тип данных ‘float64’ — вещественные числа (числа с плавающей точкой) длинной 64 бита. А его размер:
Тогда массив a — 192 байта, массив b — 384 байта. А в общем, получается, 576 байт — что очень мало для современных объемов оперативной памяти, но и реальные объемы данных, которые сейчас приходится обрабатывать совсем немаленькие.
Мы с вами собирались ответить на вопросы производительности вычислений в NumPy, но это тоже тема отдельной главы. Могу лишь сказать, что на самом деле скорость вычислений, очень сильно зависит от того кода, который вы пишите. Например, частое копирование и присваивание массивов, приводит к бесполезному потреблению памяти, а работа универсальных функций NumPy без дополнительных настроек, особенно в циклах, так же может выполняться несколько медленнее. В общем задача по использованию всего вычислительного потенциала программного обеспечения и железа, не такая уж и простая, но определенно решаемая задача.
3.3. Напоследок
Если вы новичок, то очень скоро поймете, что в использовании NumPy так же прост как и Python. Но, рано или поздно, дело дойдет до сложных задач и вот тогда начнется самое интересное: документации не хватает, ничего не гуглится, а бесчисленные «почти» подходящие советы приводят к необъяснимым сверхъестественным последствиям. Что делать в такой ситуации?
- гуглить упорнее и спускаться к самому дну поисковой выдачи;
- гуглить на английском языке, потому что, на английском информации на порядки больше чем на русском;
- если не помог пункт 2, то это означает, что вы просто маньяк какой-то, и что бы решить свою маниакальную задачу, вам придется гуглить на китайском языке, потому что на китайском информации на порядки больше чем на английском.
Это шутка и серьезная рекомендация одновременно. Но, если говорить абсолютно серьезно, то просто придерживайтесь здравого смысла. Где этот здравый смысл начинается, а где заканчивается в конкретной задаче сказать очень трудно. import this вам в помощь:
Если вы раньше пользовались R или matlab, то вас тоже ожидает много приятных сюрпризов, по крайней мере один — придется меньше стучать по клавиатуре.
Источник
Изучение NumPy с визуальными примерами для начинающих
Пакет NumPy является незаменимым помощником Python. Он тянет на себе анализ данных, машинное обучение и научные вычисления, а также существенно облегчает обработку векторов и матриц. Некоторые ведущие пакеты Python используют NumPy как основной элемент своей инфраструктуры. К их числу относятся scikit-learn, SciPy, pandas и tensorflow. Помимо возможности разобрать по косточкам числовые данные, умение работать с NumPy дает значительное преимущество при отладке более сложных сценариев библиотек.
Содержание
В данной статье будут рассмотрены основные способы использования NumPy на примерах, а также типы представления данных (таблицы, картинки, текст и так далее) перед их последующей подачей модели машинного обучения.
Создание массивов NumPy
Можно создать массив NumPy (он же ndarray), передав ему список Python, используя np.array() . В данном случае Python создает массив, который выглядит следующим образом:
Нередки случаи, когда необходимо, чтобы NumPy инициализировал значения массива.
Есть вопросы по Python?
На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!
Telegram Чат & Канал
Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!
Паблик VK
Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!
Для этого NumPy использует такие методы, как ones() , zeros() и random.random(). Требуется просто передать им количество элементов, которые необходимо сгенерировать:
После создания массивов можно манипулировать ими довольно любопытными способами.
Арифметические операции над массивами NumPy
Создадим два массива NumPy и продемонстрируем выгоду их использования.
Массивы будут называться data и ones :
При сложении массивов складываются значения каждого ряда. Это сделать очень просто, достаточно написать data + ones :
Новичкам может прийтись по душе тот факт, что использование абстракций подобного рода не требует написания циклов for с вычислениями. Это отличная абстракция, которая позволяет оценить поставленную задачу на более высоком уровне.
Помимо сложения, здесь также можно выполнить следующие простые арифметические операции:
Довольно часто требуется выполнить какую-то арифметическую операцию между массивом и простым числом. Ее также можно назвать операцией между вектором и скалярной величиной . К примеру, предположим, в массиве указано расстояние в милях, и его нужно перевести в километры. Для этого нужно выполнить операцию data * 1.6 :
Как можно увидеть в примере выше, NumPy сам понял, что умножить на указанное число нужно каждый элемент массива. Данный концепт называется трансляцией, или broadcating. Трансляция бывает весьма полезна.
Индексация массива NumPy
Массив NumPy можно разделить на части и присвоить им индексы. Принцип работы похож на то, как это происходит со списками Python.
Агрегирование в NumPy
Дополнительным преимуществом NumPy является наличие в нем функций агрегирования:
Функциями min() , max() и sum() дело не ограничивается.
- mean() позволяет получить среднее арифметическое;
- prod() выдает результат умножения всех элементов;
- std нужно для среднеквадратического отклонения.
Это лишь небольшая часть довольно обширного списка функций агрегирования в NumPy.
Использование нескольких размерностей NumPy
Все перечисленные выше примеры касаются векторов одной размерности . Главным преимуществом NumPy является его способность использовать отмеченные операции с любым количеством размерностей.
Создание матриц NumPy на примерах
Созданные в следующей форме списки из списков Python можно передать NumPy. Он создаст матрицу, которая будет представлять данные списки:
Упомянутые ранее методы ones() , zeros() и random.random() можно использовать так долго, как того требует проект.
Достаточно только добавить им кортеж, в котором будут указаны размерности матрицы, которую мы создаем.
Арифметические операции над матрицами NumPy
Матрицы можно складывать и умножать при помощи арифметических операторов ( + — * / ). Стоит, однако, помнить, что матрицы должны быть одного и того же размера . NumPy в данном случае использует операции координат:
Арифметические операции над матрицами разных размеров возможны в том случае, если размерность одной из матриц равно одному. Это значит, что в матрице только один столбец или один ряд. В таком случае для выполнения операции NumPy будет использовать правила трансляции:
dot() Скалярное произведение NumPy
Главное различие с обычными арифметическими операциями здесь в том, что при умножении матриц используется скалярное произведение. В NumPy каждая матрица может использовать метод dot() . Он применяется для проведения скалярных операций с рассматриваемыми матрицами:
На изображении выше под каждой фигурой указана ее размерность. Это сделано с целью отметить, что размерности обеих матриц должны совпадать с той стороны, где они соприкасаются. Визуально представить данную операцию можно следующим образом:
Индексация матрицы NumPy
Операции индексации и деления незаменимы, когда дело доходит до манипуляции с матрицами:
Агрегирование матриц NumPy
Агрегирование матриц происходит точно так же, как агрегирование векторов:
Используя параметр axis , можно агрегировать не только все значения внутри матрицы, но и значения за столбцами или рядами.
Транспонирование и изменение формы матриц в numpy
Нередки случаи, когда нужно повернуть матрицу. Это может потребоваться при вычислении скалярного произведения двух матриц. Тогда возникает необходимость наличия совпадающих размерностей. У массивов NumPy есть полезное свойство под названием T , что отвечает за транспонирование матрицы.
Некоторые более сложные ситуации требуют возможности переключения между размерностями рассматриваемой матрицы. Это типично для приложений с машинным обучением, где некая модель может запросить определенную форму вывода, которая является отличной от формы начального набора данных. В таких ситуациях пригодится метод reshape() из NumPy. Здесь от вас требуется только передать новые размерности для матрицы. Для размерности вы можете передать -1 , и NumPy выведет ее верное значение, опираясь на данные рассматриваемой матрицы:
Еще больше размерностей NumPy
NumPy может произвести все вышеперечисленные операции для любого количества размерностей. Структура данных, расположенных центрально, называется ndarray , или n-мерным массивом.
В большинстве случаев для указания новой размерности требуется просто добавить запятую к параметрам функции NumPy:
На заметку: Стоит иметь в виду, что при выводе 3-мерного массива NumPy результат, представленный в виде текста, выглядит иначе, нежели показано в примере выше. Порядок вывода n-мерного массива NumPy следующий — последняя ось зацикливается быстрее всего, а первая медленнее всего. Это значит, что вывод np.ones((4,3,2)) будет иметь вид:
Примеры работы с NumPy
Подытожим все вышесказанное. Вот несколько примеров полезных инструментов NumPy, которые могут значительно облегчить процесс написания кода.
Математические формулы NumPy
Необходимость внедрения математических формул, которые будут работать с матрицами и векторами, является главной причиной использования NumPy. Именно поэтому NumPy пользуется большой популярностью среди представителей науки. В качестве примера рассмотрим формулу среднеквадратичной ошибки, которая является центральной для контролируемых моделей машинного обучения, что решают проблемы регрессии:
Реализовать данную формулу в NumPy довольно легко:
Главное достоинство NumPy в том, что его не заботит, если predictions и labels содержат одно или тысячи значение (до тех пор, пока они оба одного размера). Рассмотрим пример, последовательно изучив четыре операции в следующей строке кода:
У обоих векторов predictions и labels по три значения. Это значит, что в данном случае n равно трем. После выполнения указанного выше вычитания мы получим значения, которые будут выглядеть следующим образом:
Затем мы можем возвести значения вектора в квадрат:
Теперь мы вычисляем эти значения:
Таким образом мы получаем значение ошибки некого прогноза и score за качество модели.
Представление данных NumPy
Задумайтесь о всех тех типах данных, которыми вам понадобится оперировать, создавая различные модели работы (электронные таблицы, изображения, аудио и так далее). Очень многие типы могут быть представлены как n-мерные массивы:
Таблицы NumPy — примеры использования таблиц
Таблица значений является двумерной матрицей. Каждый лист таблицы может быть отдельной переменной. Для работы с таблицами в Python чаще всего используется pandas.DataFrame , что задействует NumPy и строит поверх него.
Аудио и временные ряды в NumPy
По сути аудио файл — это одномерный массив семплов. Каждый семпл представляет собой число, которое является крошечным фрагментов аудио сигнала. Аудио CD-качества может содержать 44 100 семплов в секунду, каждый из которых является целым числом в промежутке между -32767 и 32768. Это значит, что десятисекундный WAVE-файл CD-качества можно поместить в массив NumPy длиной в 10 * 44 100 = 441 000 семплов.
Хотите извлечь первую секунду аудио? Просто загрузите файл в массив NumPy под названием audio , после чего получите audio[: 44100] .
Фрагмент аудио файла выглядит следующим образом:
То же самое касается данных временных рядов, например, изменения стоимости акций со временем.
Обработка изображений в NumPy
Изображение является матрицей пикселей по размеру (высота х ширина).
Если изображение черно-белое, то есть представленное в полутонах, каждый пиксель может быть представлен как единственное число. Обычно между 0 (черный) и 255 (белый). Хотите обрезать квадрат размером 10 х 10 пикселей в верхнем левом углу картинки? Просто попросите в NumPy image[:10, :10] .
Вот как выглядит фрагмент изображения:
Если изображение цветное, каждый пиксель представлен тремя числами. Здесь за основу берется цветовая модель RGB — красный (R), зеленый (G) и синий (B).
В данном случае нам понадобится третья размерность, так как каждая клетка вмещает только одно число. Таким образом, цветная картинка будет представлена массивом ndarray с размерностями: (высота х ширина х 3).
Обработка текста в NumPy на примерах
Когда дело доходит до текста, подход несколько меняется. Цифровое представление текста предполагает создание некого python словаря, то есть инвентаря всех уникальных слов, которые бы распознавались моделью, а также векторно (embedding step). Попробуем представить в цифровой форме цитату из стихотворения арабского поэта Антара ибн Шаддада, переведенную на английский язык:
“Have the bards who preceded me left any theme unsung?”
Перед переводом данного предложения в нужную цифровую форму модель должна будет проанализировать огромное количество текста. Здесь можно обработать небольшой набор данный, после чего использовать его для создания словаря из 71 290 слов.
Предложение может быть разбито на массив токенов, что будут словами или частями слов в зависимости от установленных общих правил:
Затем в данной таблице словаря вместо каждого слова мы ставим его id :
Однако данные id все еще не обладают достаточным количеством информации о модели как таковой. Поэтому перед передачей последовательности слов в модель токены/слова должны быть заменены их векторными представлениями. В данном случае используется 50-мерное векторное представление Word2vec.
Здесь ясно видно, что у массива NumPy есть несколько размерностей [embedding_dimension x sequence_length] . На практике все выглядит несколько иначе, однако данное визуальное представление более понятно для разъяснения общих принципов работы.
Для лучшей производительности модели глубокого обучения обычно сохраняют первую размерность для пакета. Это происходит из-за того, что тренировка модели происходит быстрее, если несколько примеров проходят тренировку параллельно. Здесь особенно полезным будет reshape() . Например, такая модель, как BERT, будет ожидать ввода в форме: [batch_size, sequence_length, embedding_size] .
Теперь мы получили числовой том, с которым модель может работать и делать полезные вещи. Некоторые строки остались пустыми, однако они могут быть заполнены другими примерами, на которых модель может тренироваться или делать прогнозы.
(На заметку: Поэма, строчку из которой мы использовали в примере, увековечила своего автора в веках. Будучи незаконнорожденным сыном главы племени от рабыни, Антара ибн Шаддан мастерски владел языком поэзии. Вокруг исторической фигуры поэта сложились мифы и легенды, а его стихи стали частью классической арабской литературы).
Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»
Источник