Повышение эффективности математики навигация по операциям с массивами Numpy

Улучшение математической навигации в Numpy при работе с массивами

 

В этой статье мы узнаем о мощности одной из известных и полезных библиотек Python для анализа данных – NumPy, где основной структурой данных для хранения элементов и выполнения операций является многомерный массив. Мы увидим, как эта динамическая библиотека делает сложные математические задачи эффективными с точки зрения затрат памяти и временной сложности. Также узнаем, как можно упростить манипулирование и преобразование данных с помощью простых операций. 

 

Что такое NumPy?

 

NumPy, Scipy и Matplotlib – это библиотеки Python, используемые в проектах Data Science, которые предоставляют функциональность, подобную MATLAB. 

   

В основном, NumPy имеет следующие особенности:

  1. Типизированные многомерные массивы (матрицы)
  2. Быстрые числовые вычисления (математика с матрицами)
  3. Математические функции высокого уровня 

NumPy расшифровывается как Numerical Python, это фундаментальный пакет, необходимый для высокопроизводительных вычислений и анализа данных. NumPy необходим для числовых вычислений в Python, так как он разработан для эффективной работы с большими массивами данных.

 

Различные способы создания массивов NumPy

 

Прежде чем приступить к операциям с массивами NumPy, наша первая задача – стать опытным создателем массивов NumPy, исходя из наших требований исходя из поставленной задачи. 

Существует несколько способов создания массивов NumPy. Ниже приведены некоторые стандартные и практические методы:

Случай 1: Использование метода np.ones для создания массива из единиц:

Если нам нужно создать массив только из “единиц”, мы можем использовать этот метод.

np.ones((3,5), dtype=np.float32)
#Вывод
[[1. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]

 

Случай 2: Использование метода np.zeros для создания массива из нулей:

Если нам нужно создать массив только из “нулей”, мы можем использовать этот метод.

np.zeros((6,2), dtype=np.int8)
# Вывод
[[0 0]
 [0 0]
 [0 0]
 [0 0]
 [0 0]
 [0 0]]

 

Случай 3: Использование метода np.arange:

Вы можете использовать этот метод, если вам нужно создать массив элементов, следующих за последовательностью.

np.arange(1334,1338)
#Вывод
[1334 1335 1336 1337]

 

Случай 4: Использование метода np.concatenate:

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

A = np.ones((2,3))
B = np.zeros((4,3))
C = np.concatenate([A, B])
#Вывод
[[1. 1. 1.]
 [1. 1. 1.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

 

Случай 5: Использование метода np.random.random:

Это полезно при создании массива с случайными значениями. 

np.random.random((2,3))
#Вывод
[[0.30512345 0.10055724 0.89505387]
 [0.36219316 0.593805   0.7643694 ]]

 

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

 

Давайте обсудим основные свойства массива NumPy на примере:

Код:

a = numpy.array([[1,2,3],[4,5,6]],dtype=numpy.float32)
# Размеры массива, форма и типы данных
print (a.ndim, a.shape, a.dtype)
Вывод:
2 (2, 3) float32

 

Исходя из приведенного выше кода, у нас есть следующие моменты, которые следует запомнить в качестве вывода:

  1. Массивы могут иметь любую размерность как положительное целое число, включая ноль (соответствует скалярному значению).
  2. Массивы имеют тип и могут иметь типы данных, такие как np.uint8, np.int64, np.float32, np.float64.
  3. Массивы плотные. Каждый элемент массива существует и имеет один и тот же тип.

Код:

# Изменение формы массивов
a = numpy.array([1,2,3,4,5,6])
a = a.reshape(3,2)              
#Вывод: 
[[1 2]                 
[3 4]                           
[5 6]]

a = a.reshape(2,-1)
#Вывод: 
[[1 2 3]
 [4 5 6]]

a = a.ravel()
#Вывод:  
[1 2 3 4 5 6]

 

Важные моменты, которые следует запомнить:

  1. Общее число элементов в массиве не может изменяться после операции изменения формы.
  2. Для определения формы оси используйте -1.
  3. По умолчанию элементы хранятся в формате по строкам, в то время как в MATLAB формат столбцовый.

 

Вещание массивов Numpy

 

Вещание позволяет выполнять операции над массивами разных форм, пока они совместимы. Меньшие размерности массива виртуально расширяются для соответствия размерностям большего массива.

   

Код:

# Вещание массивов
a = numpy.array([[1, 2], [3, 4], [5, 6]])
b = numpy.array([10, 20])
c = a + b  # Вещание массива 'b' для соответствия размерностям 'a'

 

В приведенном примере используется двумерный массив NumPy ‘a’ с размерностью (3, 2) и одномерный массив ‘b’ с формой (2). Вещание позволяет операции ‘a + b’ виртуально расширить ‘b’ для соответствия ‘a’ во втором измерении, что приводит к поэлементному сложению между ‘a’ и расширенным ‘b’.

 

Индексирование и срезы массивов

 

  1. Срезы являются представлениями. Запись в срез перезаписывает исходный массив.
  2. Список или логический массив также могут использоваться для индексации.
  3. Синтаксис индексирования Python: 

начальный_индекс: конечный_индекс: шаг

Код:

a = list(range(10)) 

 # первые 3 элемента
a[:3] # индексы 0, 1, 2 

# последние 3 элемента
a[-3:] # индексы 7, 8, 9 

# индексы 3, 5, 7 
a[3:8:2] 

# индексы 4, 3, 2 (этот пример сложнее)
a[4:1:-1] 

 

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

# Выбрать все, кроме граничного пикселя 
pixel_matrix[1:-1,1:-1]         

# Поменять порядок каналов 
pixel_matrix = pixel_matrix[:,:,::-1]

# Установить темные пиксели в черный цвет  
pixel_matrix[pixel_matrix<10] = 0

# выбрать 2-ую и 4-ую строку        
pixel_matrix[[1,3], :]  

 

Агрегация и сокращение массивов

 

Теперь мы начнем с операций агрегации над массивами numpy. Обычно вы можете выполнить следующие операции:

  1. Поиск суммы и произведения всех элементов массива.
  2. Поиск максимального и минимального элемента в массиве
  3. Найти количество определенного элемента в массиве
  4. Мы также можем найти другие параметры, используя модуль линейной алгебры, включая определитель матрицы, след матрицы, собственные значения и собственные векторы матрицы и т.д.

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

Случай 1: Алгебраическая сумма всех элементов, присутствующих в массиве

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.sum())
#Вывод: 
21

 

Случай 2: Максимальный элемент в массиве

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.max())
#Вывод: 
6

 

Случай 3: Минимальный элемент в массиве

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.min())
#Вывод: 
1

 

Случай 4: Положение/индекс элемента в массиве, где находится максимальный элемент

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.argmax())
#Вывод: 
5

 

Случай 5: Положение/индекс элемента в массиве, где находится минимальный элемент

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.argmin())
#Вывод: 
0

 

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

Случай 6: Среднее значение всех элементов в массиве

array_1 = numpy.array([[1,2,3], [4,5,6]])
print(array_1.mean())
#Вывод: 
3.5

 

Случай 7: Скалярное произведение двух многомерных массивов

array_1 = numpy.array([[1,2], [4,5]])
array_2 = numpy.array([[1,-1,2], [3,7,-2]])
t = array_1.dot(array_2)
print(t)
#Вывод: 
[[ 7 13 -2]
 [19 31 -2]]

 

Векторизация в массивах NumPy

 

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

Код:

a = numpy.array([1, 2, 3, 4, 5])
b = numpy.array([10, 20, 30, 40, 50])
c = a + b  # Поэлементное сложение без явных циклов

 

Исходя из приведенного выше примера, можно увидеть, что создаются два массива NumPy с именами ‘a’ и ‘b’. При выполнении операции ‘a + b’, где мы выполняем поэлементное сложение между массивами с использованием концепции векторизации, получаем новый массив ‘c’, содержащий сумму соответствующих элементов из ‘a’ и ‘b’. Таким образом, благодаря поэлементным операциям программа избегает выполнения явных циклов и использует оптимизированные процедуры для эффективных вычислений.

 

Конкатенация массивов

 

Случай 1: Предположим, у вас есть два или более массива для объединения с помощью функции concatenate, где вам нужно объединить кортеж массивов по строкам.

Код:

# объединение 2 или более массивов с использованием функции concatenate по строкам
numpy_array_1 = numpy.array([1,2,3])
numpy_array_2 = numpy.array([4,5,6])
numpy_array_3 = numpy.array([7,8,9])
array_concatenate = numpy.concatenate((numpy_array_1, numpy_array_2, numpy_array_3))
print(array_concatenate)
#Вывод:
[1 2 3 4 5 6 7 8 9]

 

Случай 2: Предположим, у вас есть массив с более чем одним измерением; тогда, чтобы объединить массивы, вы должны указать ось, вдоль которой они должны быть объединены. В противном случае объединение будет выполняться вдоль первого измерения. 

Код:

# объединение 2 или более массивов с использованием функции concatenate по столбцам
array_1 = numpy.array([[1,2,3], [4,5,6]])
array_2 = numpy.array([[7,8,9], [10, 11, 12]])
array_concatenate = numpy.concatenate((array_1, array_2), axis=1)
print(array_concatenate)
#Вывод:
[[ 1  2  3  7  8  9]
 [ 4  5  6 10 11 12]]

 

Математические функции и универсальные функции 

 

Эти универсальные функции также известны как ufuncs. В них выполняются операции поэлементно. Например:

  1. np.exp
  2. np.sqrt
  3. np.sin
  4. np.cos
  5. np.isnan

Код:

A = np.array([1,4,9,16,25])
B = np.sqrt(A)
#Вывод
[1. 2. 3. 4. 5.]

 

Сравнение производительности

 

При выполнении численных вычислений Python требует много времени при больших расчетах. Если мы возьмем матрицу размером 1000 x 1000 и выполним умножение матриц, то время, затрачиваемое Python и numpy, будет следующим:

  1. Тройной цикл Python занимает более 10 минут
  2. Numpy занимает около 0,03 секунды

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

 

Заключение

 

В этой статье мы обсудили массивы numpy. Итак, чтобы закончить нашу сессию, давайте подведем итоги преимуществ numpy перед Python:

  1. Numpy ориентирован на вычисления с использованием массивов.
  2. Numpy эффективно реализован многомерные массивы.
  3. Numpy в основном предназначен для научных вычислений.
  4. Numpy содержит стандартные математические функции для более быстрого вычисления на массивах без циклов.
  5. Numpy имеет встроенные модули линейной алгебры и генерации случайных чисел для работы с ними и возможности преобразования Фурье.
  6. Numpy также содержит инструменты для чтения и записи массивов на диск и работы с отображаемыми в памяти файлами.

    Арьян Гарг – студент по специальности “Электротехника”, находится на последнем курсе бакалавриата. Его интересы лежат в области веб-разработки и машинного обучения. Он следует этому интересу и стремится работать больше в этих направлениях.