Библиотека NumPy: как использовать для анализа данных
Библиотека NumPy: как использовать для анализа данных
Язык Python и его библиотеки часто используют, чтобы обрабатывать и анализировать большие объёмы данных. Разбираем, как устроена одна из таких библиотек.
NumPy — это библиотека Python, которая упрощает работу с массивами данных. Массивы — это большие наборы чисел, которые часто используются в науке, аналитике и разработке. NumPy позволяет выполнять с этими данными сложные математические операции быстрее, чем со стандартными инструментами Python.
С помощью NumPy можно хранить данные в виде массивов и выполнять вычисления мгновенно. Например, для расчёта общего дохода за день достаточно одной операции над массивом продаж, без необходимости перебора каждого товара. Библиотека NumPy работает так быстро, потому что частично написана на C и С++ — компилируемых языках. С ними вычисления быстрее, чем на интерпретируемых языках, к которым относится Python.
NumPy используется там, где нужно работать с большими объёмами информации или проводить сложные вычисления: в анализе данных, машинном обучении, научных исследованиях. Рассмотрим примеры.
● Анализ данных. Например, платформы вроде Яндекс Метрики анализируют данные о поведении пользователей. Эти данные можно выгрузить для проверки гипотез. Бывает, что в массиве есть данные с пропусками и эти пропуски обозначаются различно. Например None — встроенный объект Python, который означает «ничего» или «пустоту» и используется для общего указания отсутствия данных. NaN, или Not a Number, — специальное значение, применяется в числовых вычислениях, в том числе с массивами NumPy, где важно не останавливать процесс из-за пропусков, а учитывать их.
В зависимости от цели исследования аналитик по-разному работает с пропусками. Один из вариантов — привести их к одному виду. Например, заменить все None на NaN. Но просто командой replace этого не сделать: Python и Pandas не поймут, что от них хотят.
Чтобы заменить значения на NaN, нужно импортировать библиотеку NumPy (хотя встретить NaN можно даже без импорта библиотеки).
Код замены будет выглядеть так:
import pandas as pd # Импортируем библиотеку
import numpy as np # Импортируем библиотеку
df['column_name'] = df['column_name'].replace({None: np.nan}) #
● df['column_name'] — обращаемся к определённому столбцу в данных;
● replace({None: np.nan}) — заменяем значение None на NaN и сообщаем, что это объект NumPy.
Здесь могут появиться вопросы: правильно ли приводить значения к одному виду? Что делать дальше с пропусками: удалить, заменить или вообще не трогать?
Такие задачи и вопросы разбирают на курсе «Аналитик данных». Начинают с основ Python и постепенно переходят к продвинутым задачам по визуализации данных, статистическому анализу и A/B-тестированию
Аналитики чаще используют Pandas, а в NumPy как в отдельную библиотеку не погружаются. В Data Science наоборот: чаще работают с Numpy напрямую. Но бывает, что и аналитики применяют чистый NumPy, а специалист по Data Science столкнулся с несложной задачей по обработке данных
● Машинное обучение. В алгоритмах машинного обучения нужно работать с большими массивами данных: обучающие выборки могут содержать миллионы строк с различными параметрами. NumPy помогает быстро обрабатывать такие данные и обучать модели. Например, музыкальные стриминговые сервисы используют алгоритмы машинного обучения, чтобы анализировать предпочтения пользователей и персонализировать плейлисты. NumPy позволяет быстро обрабатывать огромные массивы данных с рейтингами и поведенческими метриками, чтобы предложить пользователю музыку по вкусу.
● Научные исследования. В медицинских исследованиях, например при анализе генома, нужно обрабатывать миллионы строк данных о последовательностях ДНК. NumPy помогает биологам быстрее анализировать данные и находить корреляции, что ускоряет процесс разработки новых лекарств.
● Матричные вычисления. При работе с большими дифференциальными уравнениями (производные или градиент) сложных физических или химических процессов, чтобы выдавать конечные состояния слоёв материала или агрегата. Здесь NumPy используют как альтернативу MatLab, если хорошо разбираются в Python.
Когда студенты приходят на курс по аналитике или программированию, им редко приходится устанавливать ПО: на обучающей платформе уже стоит окружение для обучения. Но для работы над проектами после учёбы будет полезно знать, как подключить библиотеку.
Для работы с NumPy нужно установить окружение Python, а затем саму библиотеку. Есть три способа это сделать.
1. Через менеджер пакетов pip — самый популярный способ установки. Если установлен Python, то в командную строку нужно ввести:
pip install numpy
2. Через Anaconda — бесплатную платформу для работы с Python. В ней есть основные инструменты для работы с данными: Python, библиотеки NumPy, Pandas, Matplotlib, а также Jupyter Notebook — среда для написания и выполнения кода. Чтобы установить NumPy, используют команду:
conda install numpy
Чтобы работать с библиотекой в Jupyter Notebook, его нужно запустить из консоли с помощью команды jupyter-notebook, и в новом блокноте ввести команду import numpy as np.
3. Через IDE — среду разработки. Например, в PyCharm и Visual Studio Code можно установить NumPy прямо из интерфейса. При запуске скрипта с использованием NumPy IDE автоматически предлагает установить библиотеку.
В основе NumPy — массивы (arrays). С ними работать с данными быстрее и эффективнее, чем со стандартными списками Python. Массивы NumPy отличаются от обычных списков способом хранения данных: они фиксированного размера, располагаются в памяти компактно и позволяют выполнять математические операции над целыми наборами чисел сразу. Например, приложению с прогнозом погоды нужно обрабатывать данные о температуре, ветре и осадках каждый час для нескольких городов. NumPy позволяет хранить эту информацию в виде массивов и объединять данные за разные дни.
Разберём пример, где складывают элементы двух списков с помощью цикла. Это работает, но выглядит громоздко, особенно если массивы будут больше:
# Два списка с данными
a = [1, 2, 3, 4, 5]
b = [10, 20, 30, 40, 50]
# Сложение двух списков поэлементно
result = []
for i in range(len(a)):
result.append(a[i] + b[i])
print(result) # Выведет [11, 22, 33, 44, 55]
NumPy упрощает код и ускоряет вычисления. Массивы, которые хранят числа, ведут себя почти как списки, но с ними можно делать математические операции напрямую. Вместо цикла NumPy позволяет просто сложить два массива одной строкой — a + b. Операция сложения a + b работает одновременно для всех элементов массивов, что делает код короче и понятнее.
Есть два вида массивов: одномерные и двумерные, или векторы и матрицы. Чтобы создать массив, нужна функция array(). Попробуем создать одномерный массив. Здесь и далее будем считать, что импортировали библиотеку с помощью команды import numpy as np:
a = np.array([1, 2, 3, 4, 5])
Здесь использовали array(), чтобы преобразовать Python-список в массив. С помощью print() смотрим результат.
Матрицы создаются с помощью передачи списка списков в функцию np.array(). В нашем случае это два списка — [1, 2, 3] и [4, 5, 6], которые помещаем в один:
b = np.array([[1, 2, 3], [4, 5, 6]]).
Чтобы объединять массивы, в NumPy используют несколько функций.
1. np.concatenate() объединяет массивы по заданной оси (горизонтально или вертикально). Для одномерных массивов ось не имеет значения, так как это просто последовательность элементов. Поэтому np.concatenate() по умолчанию «выстраивает» массивы один за другим:
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
combined = np.concatenate((a, b)) # объединение одномерных массивов
print(combined)
# Вывод: [1 2 3 4 5 6]
Для многомерных массивов np.concatenate() по умолчанию объединяет массивы по оси 0 или по строкам:
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
combined = np.concatenate((a, b), axis=0)
print(combined)
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
Чтобы объединить многомерные массивы по столбцам, или оси 1, добавляем параметр axis=1:
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
combined = np.concatenate((a, b), axis=1)
print(combined)
# [[1 2 5 6]
# [3 4 7 8]]
2. np.vstack() объединяет массивы вертикально, добавляя один массив под другим. Это упрощённый способ вертикального объединения, который всегда соединяет массивы по оси 0:
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6]])
combined = np.vstack((a, b))
print(combined)
# [[1 2]
# [3 4]
# [5 6]]
3. np.hstack() объединяет массивы горизонтально, добавляя один массив к другому слева направо — по оси 1:
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
combined = np.hstack((a, b))
print(combined)
# [[1 2 5 6]
# [3 4 7 8]]
1. np.arange() используется для создания одномерных массивов с равномерно распределёнными значениями в заданном диапазоне. Пригодится для генерации массивов чисел для вычислений или моделирования.
Синтаксис функции выглядит так: numpy.arange(start, stop, step, dtype=None), где:
○ start (по умолчанию 0) — начало последовательности;
○ stop — конец последовательности (не включается в массив);
○ step (по умолчанию 1): — шаг между значениями;
○ dtype (необязательно) — тип данных массива.
Простой диапазон чисел от 0 до 4 с шагом 1:
a = np.arange(5)
print(a) # [0 1 2 3 4]
Можно использовать arange для создания временных шкал, например для моделирования ежедневных событий:
days = np.arange(1, 31) # Дни месяца
print(days) # [ 1 2 3 ... 29 30]
2. np.linspace() используется для создания массива с равномерно распределёнными значениями в заданном диапазоне. Это важно, например, при создании графиков. Главное отличие от np.arange(): вместо шага указывается количество элементов.
Синтаксис: np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None), где:
● start — начало диапазона;
● stop — конец диапазона;
● num (по умолчанию 50) — количество элементов;
● endpoint (по умолчанию True) — включать ли конец диапазона;
● retstep (по умолчанию False) — возвращать ли шаг между элементами;
● dtype — тип данных массива.
Код для графика временных значений:
time = np.linspace(0, 10, 100) # 100 точек от 0 до 10 секунд
1. Математические операции
На примере массива p = np.array([5, 6, 7, 8]) покажем операции и между массивами, и между массивом и числом.
При сложении числа с массивом это число прибавляется к каждому элементу:
p + 2
# Результат: array([7, 8, 9, 10])
При сложении двух массивов их элементы складываются поэлементно:
p + p
# Результат: array([10, 12, 14, 16])
Если вычесть число из массива, оно вычитается из каждого элемента:
p - 6
# Результат: array([-1, 0, 1, 2])
При вычитании массива из массива вычитаются соответствующие элементы:
p - p
# Результат: array([0, 0, 0, 0])
Массив можно умножить на число, и каждый элемент будет умножен на это число:
p * 3
# Результат: array([15, 18, 21, 24])
Также можно умножить два массива поэлементно:
p * p
# Результат: array([ 25, 36, 49, 64])
Деление массива на число выполняется поэлементно:
p / 3
# Результат: array([1.7, 2, 2.3, 4. ])
2. Статистические операции min() и max() — возвращают минимальное и максимальное значения массива:
p = np.array([2.1, 2.5, 2.8, 3.2, 4])
print(np.min(a)) # Выведет 2.1
print(np.max(a)) # Выведет 4
Представим, что в приложении для расчёта бюджета есть массив данных о расходах за месяц. Нужно вычислить общую сумму трат, самый большой и самый маленький расход.
Программист будет использовать базовые функции NumPy. Аналитик — библиотеку Pandas. Она позволяет работать с табличными данными: можно легко добавлять новые колонки, фильтровать или агрегировать данные. Это полезно, если нужно анализировать не только значения, но и сопутствующую информацию, например даты или категории расходов.
mean() — вычисляет среднее значение всех элементов массива. Полезна для анализа данных — например, узнать среднюю температуру за несколько дней:
a = np.array([10.5, 11, 8, 13.2, 14])
print(np.mean(a)) # 11.34
median() — рассчитывает медиану, или центральное значение набора данных:
data = np.array([38, 45, 51, 63, 77])
print(np.median(data)) # 51.0
Стандартное отклонение (std()) показывает, насколько разбросаны данные относительно среднего значения:
data = np.array([15, 23, 34, 45, 56])
print(np.std(data)) # 14.732277488562318
3. Операции с линейной алгеброй
Транспонирование матрицы (поменять строки и столбцы местами) нужно, например, чтобы переключиться с анализа данных по кварталам на анализ по товарам. В чистом NumPy для этого используют функцию np.transpose(). Но аналитик снова обратится к библиотеке Pandas и методу .transpose() или атрибуту .T.
Разберём пример:
import pandas as pd
# Создаём DataFrame
data = {'Товар А': [100, 150], 'Товар B': [200, 250]}
df = pd.DataFrame(data, index=['Q1', 'Q2'])
print("Исходный DataFrame:")
print(df)
# Транспонируем DataFrame
df_transposed = df.T
print("\nТранспонированный DataFrame:")
print(df_transposed)
Модуль random — аналитики часто используют его, когда работают со статистическими выборками. С помощью модуля генерируют случайные выборки и таким образом проверяют, правильно ли работает код до того, как использовать его для реальных выборок.
Сгенерируем случайные числа от 0 до 1:
random_numbers = np.random.rand(5)
print(random_numbers)
# Например, [0.165, 0.345, 0.921, 0.124, 0.883]
Можно также генерировать целые числа в заданном диапазоне:
random_integers = np.random.randint(1, 10, 5)
print(random_integers)
# Например, [3, 7, 2, 9, 4]
Совет эксперта
Читать также: