Шаг 34.
Однострочники Python.
Наука о данных. Простейшие операции с двумерными массивами

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

Общее описание

    Важнейший элемент библиотеки NumPy - массивы NumPy, используемые для хранения данных, предназначенных для анализа, визуализации и различных операций. Многие более высокоуровневые библиотеки data science, например Pandas, напрямую или опосредованно основаны на массивах NumPy.

    Массивы NumPy аналогичны спискам Python, но имеют некоторые дополнительные преимущества. Во-первых, массивы NumPy занимают меньше места в памяти и чаще всего отличаются большим быстродействием. Во-вторых, массивы NumPy удобнее при обращении более чем к двум осям координат, то есть для многомерных данных (доступ к многомерным спискам и их модификация - непростые задачи). А поскольку массивы NumPy могут содержать несколько осей координат, мы будем рассматривать массивы через призму измерений (dimensions): включающий две оси координат массив - двумерный. В-третьих, функциональность доступа к массивам NumPy намного шире и включает транслирование, с которым вы познакомитесь в последующих шагах.

    В примере 3.1 приведены примеры создания одномерного, двумерного и трехмерного массивов NumPy.


Пример 3.1. Создание одномерного, двумерного и трехмерного массивов в NumPy
import numpy as np

# Создание одномерного массива из списка
a = np.array([1, 2, 3])
print(a) # [1 2 3] 

# Создание двумерного массива из списка списков
b = np.array([[1, 2], [3, 4]])
print(b) 
#  [[1 2] 
#   [3 4]]

# Создание трехмерного массива из списка списков списков 
c = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print(c)
# [[[1 2]
#   [3 4]]
#  [[5 6]
#   [7 8]]]

    Сначала мы импортировали библиотеку NumPy в наше пространство имен, указав практически стандартное название для нее: np. После импорта библиотеки мы создали массив NumPy, передав обычный список Python в качестве аргумента в функцию np.array(). Одномерный массив соответствует простому списку числовых значений (на самом деле массивы NumPy могут содержать и данные других типов, но здесь мы сосредоточим свое внимание на числах). Двумерный массив соответствует вложенному списку списков числовых значений, а трехмерный - вложенному списку списков списков числовых значений. Размерность массива NumPy определяется из количества открывающих и закрывающих скобок.

    Массивы NumPy обладают более широкими возможностями, чем встроенные списки Python. Например, над двумя массивами NumPy можно выполнять простейшие арифметические операции +, -, * и /. Эти поэлементные операции над массивами (например, сложение их с помощью оператора +) заключаются в выполнении соответствующей операции над каждым из элементов массива a с соответствующим элементом массива b. Другими словами, поэлементная операция агрегирует два элемента, расположенных на одинаковых местах в массивах a и b. В примере 3.2 приведены примеры простейших арифметических операций над двумерными массивами.


Пример 3.2. Простейшие арифметические операции с массивами
import numpy as np

a = np.array([[1, 0, 0],
              [1, 1, 1], 
              [2, 0, 0]])
b = np.array([[1, 1, 1], 
              [1, 1, 2], 
              [1, 1, 2]])
print(a + b)
# [[2 1 1]
#  [2 2 3]
#  [3 1 2]]

print(a - b)
# [[0 -1 -1]
#  [0 0 -1]
#  [1 -1 -2]]

print(a * b)
# [[1 0 0]
#  [1 1 2]
#  [2 0 0]]

print(a / b)	
# [[1. 0. 0.]
#  [1. 1. 0.5]
#  [2. 0. 0. ]]


При использовании операторов NumPy к массивам целых чисел библиотека пытается сгенерировать в качестве результата также массив целых чисел. Только при делении двух массивов целых чисел с помощью оператора деления, a / b, результат будет массивом чисел с плавающей точкой, на что указывают десятичные точки: 1., 0. и 0.5.

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

    NumPy предоставляет и многие другие средства для работы с массивами, включая функцию np.max(), вычисляющую максимальное из всех значений массива NumPy. Функция np.min() вычисляет минимальное из всех значений массива NumPy. Функция np.average() вычисляет среднее значение массива NumPy.

    В примере 3.3 приведены примеры этих трех операций.


Пример 3.3. Вычисление максимального, минимального и среднего значений массива NumPy
import numpy as np

a = np.array([[1, 0, 0],
              [1, 1, 1],
              [2, 0, 0]])

print(np.max(a))
# 2

print(np.min(a))
# 0

print(np.average(a))
# 0.6666666666666666

    Максимальное из всех значений данного массива NumPy равно 2, минимальное - 0, а среднее: (1 + 0 + 0 + 1 + 1 + 1 + 2 + 0 + 0) / 9 = 2/3. NumPy включает множество мощных инструментов, но и этих вполне достаточно для решения следующей задачи: как найти максимальный доход после уплаты налогов среди группы людей, если известны годовая зарплата и ставка налогообложения.

    На следующем шаге мы закончим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг