Numpy (числовой python)
Numpy — это библиотека Python, используемая для работы с массивами.
Numpy расшифровывается как числовой python, он используется для выполнения широкого спектра математических операций с массивами. Он также имеет функции для работы в области линейной алгебры, преобразования Фурье и матриц. В python есть list, который может работать как numpy, но list обрабатывается медленно, поэтому numpy помогает в решении проблемы, поскольку массивы NumPy хранятся в одном непрерывном месте в памяти в отличие от списков, поэтому процессы могут получать к ним доступ и манипулировать ими очень эффективно.
Чтобы установить Numpy, используем следующую команду:
pip install numpy
Установив Numpy, необходимо импортировать библиотеку, используя следующую команду:
import numpy as np
Где np — псевдоним используемый для ссылки на Numpy.
Создание массива
Объект массива в Numpy называется ndarray. Мы можем создать объект ndarray Numpy с помощью функции array() , как показано ниже
import numpy as np # creating an array x = np.array([2,4,6,8,10]) print(x) print(type(x))
Примечание: Массив может быть одномерным, двухмерным или трехмерным.
- Одномерный массив — это массив, в котором в качестве элементов используются нулевые (0-D) массивы.
- Двумерный массив — это массив, элементами которого являются одномерные (1-D) массивы.
- Трехмерный массив — массив, содержащий двумерные (2-D) массивы в качестве элементов.
Существует множество операций, которые выполняются в массивах Numpy, которые включают:
- индексация (indexing) массива numpy
- нарезка (slicing) массива numpy
- форма (shape) массива numpy
- изменение (reshape) формы массива numpy
- разделение (split) массива numpy
- соединение (join) массива numpy.
indexing массива Numpy
Мы получаем доступ к элементу массива посредством индексации с помощью порядкового номера
- Indexing (индексирование) в одномерном массиве
#indexing in 1-D array x = np.array([1, 3, 4, 6]) print(x[0])
- Indexing (индексирование) в двумерном массиве
#indexing in 2-D array y = np.array([[1,4,6,9,0], [2,7,3,9,1]]) print('2nd element on 1st row: ', y[0, 1])
slicing (нарезка) массива Numpy
Нарезка относится к переносу элементов из одного заданного индекса в другой заданный индекс.
#Slice elements from index 1 to index 5 from the following array y = np.array([10,20,30,40,50,60]) print(y[1:4])
[20 30 40]
Примечание: Результат включает начальный индекс, но исключает конечный индекс.
shape (форма) массива Numpy
Форма массива — это количество элементов в каждом измерении. Массивы Numpy имеют атрибут под названием shape который возвращает запись с каждым индексом, имеющим количество соответствующих элементов.
arr = np.array([[2,4,6,8], [8,8,3,4]]) print(arr.shape)
Приведенный выше пример возвращает (2, 4), что означает, что массив состоит из двух строк и 4 столбцов. Первая цифра представляет строку, вторая — столбцы.
reshape (изменение формы) массива Numpy
Изменение формы относится к изменению формы массива, как мы ранее указали, форма в массиве — это количество элементов в каждом измерении. Изменение формы может быть добавлением или удалением количества элементов в каждом измерении.
- Изменение формы может быть от одномерных до двумерных (из 1-D до 2-D)
z = np.array([2,4,6,8,10,12,14,16,18,20,22,24]) newarray = z.reshape(4, 3) print(newarray)
[[ 2 4 6] [ 8 10 12] [14 16 18] [20 22 24]]
Примечание: Массив был изменен с одномерного массива на двумерный массив с 4 строками и 3 столбцами.
- Изменение формы с одномерных до трехмерных (с 1-D до 3-D)
z = np.array([2,4,6,8,10,12,14,16,18,20,22,24]) newarray = z.reshape(2, 3, 2) print(newarray)
[[[ 2 4] [ 6 8] [10 12]] [[14 16] [18 20] [22 24]]]
Примечание: Само внешнее измерение будет иметь два массива, которые содержат 3 массива, каждый из которых содержит 2 элемента.
Массив объединения Numpy
Объединение означает помещение содержимого двух или более массивов в один массив.
x = np.array([10, 20, 30]) y = np.array([40, 50, 60]) arr1 = np.concatenate((x, y)) print(arr1)
[10 20 30 40 50 60]
мы можем присоединять массивы, используя функции стека, такие как stack , которые складываются вдоль столбцов.давайте приведем пример,
x = np.array([10, 20, 30]) y = np.array([40, 50, 60]) arr2 = np.vstack((x,y)) print(arr2)
[[10 20 30] [40 50 60]]
Разделение (split) массива numpy
Разделение — это операция, обратная соединению.
Объединение объединяет несколько массивов в один, а разделение разбивает один массив на несколько.Чтобы разделить массивы, мы используем функцию array_split() , где мы передаем некоторые аргументы, которые представляют собой массив, подлежащий разделению, и количество разделяемых.
x = np.array([20,40, 60,70,80,100]) arr3 = np.array_split(x, 3) print(arr3)
[array([20, 40]), array([60, 70]), array([ 80, 100])]
Примечание: Возвращаемое значение из приведенного выше примера представляет собой массив, содержащий три массива.
Самый простой способ использовать NumPy: импортировать numpy как np
NumPy , что означает Numerical Python, представляет собой библиотеку для научных вычислений, построенную на основе языка программирования Python.
Самый распространенный способ импортировать NumPy в вашу среду Python — использовать следующий синтаксис:
import numpy as np
Часть кода import numpy сообщает Python о необходимости перенести библиотеку NumPy в вашу текущую среду.
Затем as np часть кода сообщает Python, чтобы дать NumPy псевдоним np.Это позволяет вам использовать функции NumPy, просто набрав np.function_name, а не numpy.function_name.
После того, как вы импортировали NumPy, вы можете использовать встроенные в него функции для быстрого создания и анализа данных.
Как создать базовый массив NumPy
Наиболее распространенный тип данных, с которым вы будете работать в NumPy, — это массив , который можно создать с помощью функции np.array() .
В следующем коде показано, как создать базовый одномерный массив NumPy:
import numpy as np #define array x = np.array([1, 12, 14, 9, 5]) #display array print(x) [ 1 12 14 9 5] #display number of elements in array x. size 5
Вы также можете создать несколько массивов и выполнять над ними операции, такие как сложение, вычитание, умножение и т. д.
import numpy as np #define arrays x = np.array([1, 12, 14, 9, 5]) y = np.array([2, 3, 3, 4, 2]) #add the two arrays x+y array([ 3, 15, 17, 13, 7]) #subtract the two arrays x-y array([-1, 9, 11, 5, 3]) #multiply the two arrays x\*y array([ 2, 36, 42, 36, 10])
Ознакомьтесь с руководством для начинающих по NumPy, чтобы получить подробное представление обо всех основных функциях NumPy.
Возможные ошибки при импорте NumPy
Одна потенциальная ошибка, с которой вы можете столкнуться при импорте NumPy:
NameError : name 'np' is not defined
Это происходит, когда вы не можете указать псевдоним NumPy при его импорте. Прочитайте это руководство , чтобы узнать, как быстро исправить эту ошибку.
Дополнительные ресурсы
Если вы хотите узнать больше о NumPy, ознакомьтесь со следующими ресурсами:
NumPy, часть 1: начало работы

NumPy — это библиотека языка Python, добавляющая поддержку больших многомерных массивов и матриц, вместе с большой библиотекой высокоуровневых (и очень быстрых) математических функций для операций с этими массивами.
Установка NumPy
На linux — пакет python3-numpy (или аналогичный для вашей системы), или через pip. Ну или же собирать из исходников https://sourceforge.net/projects/numpy/files/NumPy/.
На Windows на том же сайте есть exe установщики. Или, если возникают проблемы, рекомендую ещё хороший сборник библиотек http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy.
Начинаем работу
Основным объектом NumPy является однородный многомерный массив (в numpy называется numpy.ndarray). Это многомерный массив элементов (обычно чисел), одного типа.
Наиболее важные атрибуты объектов ndarray:
ndarray.ndim — число измерений (чаще их называют «оси») массива.
ndarray.shape — размеры массива, его форма. Это кортеж натуральных чисел, показывающий длину массива по каждой оси. Для матрицы из n строк и m столбов, shape будет (n,m). Число элементов кортежа shape равно ndim.
ndarray.size — количество элементов массива. Очевидно, равно произведению всех элементов атрибута shape.
ndarray.dtype — объект, описывающий тип элементов массива. Можно определить dtype, используя стандартные типы данных Python. NumPy здесь предоставляет целый букет возможностей, как встроенных, например: bool_, character, int8, int16, int32, int64, float8, float16, float32, float64, complex64, object_, так и возможность определить собственные типы данных, в том числе и составные.
ndarray.itemsize — размер каждого элемента массива в байтах.
ndarray.data — буфер, содержащий фактические элементы массива. Обычно не нужно использовать этот атрибут, так как обращаться к элементам массива проще всего с помощью индексов.
Создание массивов
В NumPy существует много способов создать массив. Один из наиболее простых — создать массив из обычных списков или кортежей Python, используя функцию numpy.array() (запомните: array — функция, создающая объект типа ndarray):
Функция array() трансформирует вложенные последовательности в многомерные массивы. Тип элементов массива зависит от типа элементов исходной последовательности (но можно и переопределить его в момент создания).
Можно также переопределить тип в момент создания:
Функция array() не единственная функция для создания массивов. Обычно элементы массива вначале неизвестны, а массив, в котором они будут храниться, уже нужен. Поэтому имеется несколько функций для того, чтобы создавать массивы с каким-то исходным содержимым (по умолчанию тип создаваемого массива — float64).
Функция zeros() создает массив из нулей, а функция ones() — массив из единиц. Обе функции принимают кортеж с размерами, и аргумент dtype:
Функция eye() создаёт единичную матрицу (двумерный массив)
Функция empty() создает массив без его заполнения. Исходное содержимое случайно и зависит от состояния памяти на момент создания массива (то есть от того мусора, что в ней хранится):
Для создания последовательностей чисел, в NumPy имеется функция arange(), аналогичная встроенной в Python range(), только вместо списков она возвращает массивы, и принимает не только целые значения:
Вообще, при использовании arange() с аргументами типа float, сложно быть уверенным в том, сколько элементов будет получено (из-за ограничения точности чисел с плавающей запятой). Поэтому, в таких случаях обычно лучше использовать функцию linspace(), которая вместо шага в качестве одного из аргументов принимает число, равное количеству нужных элементов:
fromfunction(): применяет функцию ко всем комбинациям индексов
Печать массивов
Если массив слишком большой, чтобы его печатать, NumPy автоматически скрывает центральную часть массива и выводит только его уголки.
Если вам действительно нужно увидеть весь массив, используйте функцию numpy.set_printoptions:
И вообще, с помощью этой функции можно настроить печать массивов "под себя". Функция numpy.set_printoptions принимает несколько аргументов:
precision : количество отображаемых цифр после запятой (по умолчанию 8).
threshold : количество элементов в массиве, вызывающее обрезание элементов (по умолчанию 1000).
edgeitems : количество элементов в начале и в конце каждой размерности массива (по умолчанию 3).
linewidth : количество символов в строке, после которых осуществляется перенос (по умолчанию 75).
suppress : если True, не печатает маленькие значения в scientific notation (по умолчанию False).
nanstr : строковое представление NaN (по умолчанию ‘nan’).
infstr : строковое представление inf (по умолчанию ‘inf’).
formatter : позволяет более тонко управлять печатью массивов. Здесь я его рассматривать не буду, можете почитать здесь (на английском).
И вообще, пользуйтесь официальной документацией по numpy, а в этом пособии я постараюсь описать всё необходимое. В следующей части мы рассмотрим базовые операции над массивами.
Подписывайтесь, чтобы не пропустить 🙂
Для вставки кода на Python в комментарий заключайте его в теги
Быстрые поэлементные операции — Python: Numpy-массивы
Чтобы проанализировать данные, можно провести множество разных операций:
- Сравнить значения
- Поискать минимальные и максимальные значения
- Найти суммы и произведения элементов
И это далеко не полный список всех доступных преобразований. В некоторых случаях вычисления над элементами требуют использования более сложных математических операций и функций. Именно под это заточена библиотека Numpy, которая позволяет не только готовить данные к обработке, но и проводить необходимые вычисления. В этом уроке мы разберемся, как эти вычисления работают и как применять их на практике.
Поэлементные преобразования и укладывание
Numpy помогает ускорить операции и упростить синтаксис — так происходит благодаря поэлементным преобразованиям. Он позволяет оперировать с данными разной размерности. Такой подход называется укладыванием.
Чтобы погрузиться в эту тему глубже, познакомимся с распространенными задачами с арифметическими операциями над данными и выясним, как работает укладывание элементов одного массива данных в другой.
Чтобы выполнять арифметические операции со стандартными структурами данных в Python, нужно использовать циклы. Их количество и вложенность зависит от размерности. Numpy работает по-другому — логика и синтаксические конструкции в операциях над массивами остается одинаковой для структур разной размерности. Для оптимизации и повышения качества кода циклы скрыты от пользователя.
Посмотрим на пример ниже. В нем показан ряд операций над одномерным массивом данных и числовым значением, которое поэлементно применяется ко всему массиву:
import numpy as np # Исходный массив arr1 = np.array([0, 1, 2, 3, 4, 5, 6, 7]) # Значение для изменения элементов массива change_array_value = 5 print(arr1 + change_array_value) # => [ 5 6 7 8 9 10 11 12] print(arr1 - change_array_value) # => [-5 -4 -3 -2 -1 0 1 2] print(arr1 * change_array_value) # => [ 0 5 10 15 20 25 30 35] print(arr1 / change_array_value) # => [0. 0.2 0.4 0.6 0.8 1. 1.2 1.4]
Циклы в примере выше отсутствуют. Как мы уже говорили, в Numpy это называется укладыванием. Укладывание элемента в массив было разобрано на примере вектора и числа. Однако укладывать можно не только один элемент, а любой массив подходящего размера — при условии, если структура большей размерности. Посмотрим на пример прибавления элементов вектора построчно к матрице:
# Добавление вектора к матрице matrix_array = np.array([[5, 8], [8, 9]]) vector_array = np.array([1, 2]) print(matrix_array + vector_array) # => [[ 6 10] # [ 9 11]]
Чтобы выполнить те же операции над двумя массивами, также не используются циклы. Все синтаксические конструкции остаются без изменений:
# Массив для изменения значений исходного arr2 = np.array([2, 2, 2, 2, -1, -1, -1, -1]) print(arr1 + arr2) # => [2 3 4 5 3 4 5 6] print(arr1 - arr2) # => [-2 -1 0 1 5 6 7 8] print(arr1 * arr2) # => [ 0 2 4 6 -4 -5 -6 -7] print(arr1 / arr2) # => [ 0. 0.5 1. 1.5 -4. -5. -6. -7. ]
Для сравнения посмотрим, как выполняются аналогичные задачи над стандартными списками. Без циклов и генератора zip() в этом случае не обойтись:
arr1 = [0, 1, 2, 3, 4, 5, 6, 7] change_array_value = 5 arr2 = [2, 2, 2, 2, -1, -1, -1, -1] print([arr1_val + change_array_value for arr1_val in arr1]) # => [5, 6, 7, 8, 9, 10, 11, 12] print([arr1_val + arr2_val for arr1_val, arr2_val in zip(arr1, arr2)]) # => [2, 3, 4, 5, 3, 4, 5, 6]
Создатели Numpy целенаправленно разработали библиотеку, в которой выполнение функционала не зависит от размерности данных. В качестве примера приведены поэлементные операции над матрицами:
arr1 = np.array([[5, 8], [8, 9]]) arr2 = np.array([[3, 1], [7, 2]]) change_array_value = 3 print(arr1 * arr2) # => [[15 8] # [56 18]] print(arr1 / change_array_value) # => [[1.66666667 2.66666667] # [2.66666667 3. ]]
Во всех примерах выше операции с массивами Numpy производились по одному шаблону. Размерность данных не влияла на синтаксис — мы использовали одинаковые математические операторы, меняя только операнды: числа, вектора, матрицы.
Для сравнения изучим пример операций над матрицами, которые представлены стандартными списками. Здесь необходимо использовать циклы:
# Пример для аналогичных операций над стандартными списками arr1 = [[5, 8], [8, 9]] arr2 = [[3, 1], [7, 2]] change_array_value = 3 for i in range(len(arr1)): for j in range(len(arr1[0])): arr1[i][j] *= arr2[i][j] print(arr1) # => [[15, 8], # [56, 18]] for i in range(len(arr2)): for j in range(len(arr2[0])): arr2[i][j] += change_array_value print(arr2) # => [[6, 4], # [10, 5]]
При работе со стандартными списками чем больше размерность, тем больше строк кода. К этому моменту стоит относиться внимательно, ведь длина кода делает его сложнее в поддержке и может приводить к возникновению ошибок.
Как это работает на практике
В качестве практического примера решим задачу, с которой сталкивается аналитик данных в своей работе. Возьмем исторические данные по продажам ноутбуков в сети из четырех магазинов за неделю. Попробуем посмотреть отклонения от средних показателей. Средние показатели могут быть вычислены по-разному в зависимости от среза данных. Так можно смотреть на ситуацию:
- Во всей сети магазинов
- В каждом магазине по отдельности
- С распределением по дням недели
Предположим, что из базы данных сервиса выгрузили продажи в виде списка списков значений, где внешний список объединяет списки продаж по каждому дню недели для четырех магазинов:
# Продажи магазина orders = [ [7, 1, 7, 8], [4, 2, 4, 5], [3, 5, 2, 3], [8, 12, 8, 7], [15, 11, 13, 9], [21, 18, 17, 21], [25, 16, 25, 17] ] orders = np.array(orders)
После инициализации данных в виде массива можно перейти к анализу отклонений от среднего по всей сети:
# Среднее значение по всем магазинам по всем дням mean_orders_value = orders.mean() print(mean_orders_value) # => 10.5 print(orders - mean_orders_value) # => [[-3.5 -9.5 -3.5 -2.5] # [-6.5 -8.5 -6.5 -5.5] # [-7.5 -5.5 -8.5 -7.5] # [-2.5 1.5 -2.5 -3.5] # [ 4.5 0.5 2.5 -1.5] # [10.5 7.5 6.5 10.5] # [14.5 5.5 14.5 6.5]]
Средний показатель для всей сети не всегда подходит для анализа, поскольку у магазинов может быть разный объем продаж. Чтобы лучше понять ситуацию с продажами, найдем среднее по каждому магазину. В примере это среднее значение по столбцам матрицы продаж. Чтобы найти такие средние, используем метод mean() с параметром axis = 0 :
# Среднее значение по магазинам mean_by_shop = orders.mean(axis=0) print(mean_by_shop) # => [11.85714286 9.28571429 10.85714286 10.] print(orders - mean_by_shop) # =>[[-4.85714286 -8.28571429 -3.85714286 -2.] # [-7.85714286 -7.28571429 -6.85714286 -5.] # [-8.85714286 -4.28571429 -8.85714286 -7.] # [-3.85714286 2.71428571 -2.85714286 -3.] # [ 3.14285714 1.71428571 2.14285714 -1.] # [ 9.14285714 8.71428571 6.14285714 11.] # [13.14285714 6.71428571 14.14285714 7.]]
Аналитику также может потребоваться информация о дневных отклонениях. Так, например, можно обнаружить просадку продаж по вине логистов и менеджеров. Для этого необходимо найти средние по дням. К матрице продаж надо применить метод mean() с параметром axis = 1 :
# Среднее значение по дням mean_by_day = orders.mean(axis=1) print(mean_by_day) # => [ 5.75 3.75 3.25 8.75 12. 19.25 20.75] # Переформатирование вектора для укладывания по столбцам mean_by_day = mean_by_day.reshape((7,1)) print(mean_by_day) # => [[ 5.75] # [ 3.75] # [ 3.25] # [ 8.75] # [12. ] # [19.25] # [20.75]] print(orders - mean_by_day) # => [[ 1.25 -4.75 1.25 2.25] # [ 0.25 -1.75 0.25 1.25] # [-0.25 1.75 -1.25 -0.25] # [-0.75 3.25 -0.75 -1.75] # [ 3. -1. 1. -3. ] # [ 1.75 -1.25 -2.25 1.75] # [ 4.25 -4.75 4.25 -3.75]]
В примере выше используется метод reshape() — он помогает преобразовать исходную строку средних в столбец. Это принципиально необходимо для того, чтобы вектор был уложен в матрицу именно по столбцам.
Выводы
В этом уроке мы узнали, что библиотека Numpy упрощает и оптимизирует вычисления с использованием языка Python. Для этого она применяет подход, который унифицирует интерфейс работы с массивами. Все арифметические операции над массивами производятся без циклов — с использованием только самих символов операций.
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях: