Numpy для анализа данных: как эффективно работать с массивами в Python?

Введение в NumPy для анализа данных

Что такое NumPy и почему он важен для анализа данных в Python?

NumPy (Numerical Python) — это фундаментальная библиотека для научных вычислений в Python. Её ключевой особенностью являются многомерные массивы (ndarray), обеспечивающие эффективное хранение и манипулирование числовыми данными. NumPy важен для анализа данных, потому что он:

  1. Оптимизирован для численных операций: NumPy предоставляет векторизованные операции, которые выполняются значительно быстрее, чем стандартные циклы Python. Это особенно важно при работе с большими объемами данных.
  2. Основа для других библиотек: Pandas, SciPy, scikit-learn и многие другие библиотеки анализа данных построены на основе NumPy, используя его массивы как базовую структуру данных.
  3. Удобство и выразительность: NumPy предлагает мощные инструменты для индексации, срезов, маскирования и других операций над массивами, делая код более читаемым и лаконичным.

Установка NumPy: пошаговая инструкция

Установить NumPy можно с помощью pip:

pip install numpy

Или с помощью conda:

conda install numpy

После установки импортируйте библиотеку в свой скрипт:

import numpy as np

Основные типы данных в NumPy: массивы (ndarray)

Основной тип данных в NumPy — это ndarray (n-dimensional array). Массив NumPy представляет собой сетку значений, все одного типа, индексируемую кортежем неотрицательных целых чисел. Количество измерений массива называется рангом, а форма массива — это кортеж, указывающий размер массива по каждому измерению.

Создание и манипулирование массивами NumPy

Создание массивов NumPy различными способами (np.array, np.zeros, np.ones, np.arange, np.linspace)

  • np.array(): Создает массив из списка или кортежа Python.

    import numpy as np
    
    data: list[int] = [1, 2, 3, 4, 5]
    arr: np.ndarray = np.array(data)
    print(arr)  # Вывод: [1 2 3 4 5]
    
  • np.zeros(): Создает массив, заполненный нулями.

    zeros_arr: np.ndarray = np.zeros((2, 3))
    print(zeros_arr)
    # Вывод:
    # [[0. 0. 0.]
    #  [0. 0. 0.]]
    
  • np.ones(): Создает массив, заполненный единицами.

    ones_arr: np.ndarray = np.ones((3, 2))
    print(ones_arr)
    # Вывод:
    # [[1. 1.]
    #  [1. 1.]
    #  [1. 1.]]
    
  • np.arange(): Создает массив с последовательностью чисел в заданном диапазоне.

    range_arr: np.ndarray = np.arange(0, 10, 2)  # от 0 до 10 (не включая) с шагом 2
    print(range_arr)  # Вывод: [0 2 4 6 8]
    
  • np.linspace(): Создает массив с заданным количеством чисел, равномерно распределенных в заданном диапазоне.

    linspace_arr: np.ndarray = np.linspace(0, 1, 5)  # 5 чисел от 0 до 1 включительно
    print(linspace_arr)  # Вывод: [0.   0.25 0.5  0.75 1.  ]
    

Изменение формы массивов (reshape)

Метод reshape() позволяет изменить форму массива, не меняя его данные.

arr: np.ndarray = np.arange(12)
reshaped_arr: np.ndarray = arr.reshape((3, 4))  # Преобразование в массив 3x4
print(reshaped_arr)
# Вывод:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

Индексация и срезы массивов: доступ к элементам и подмассивам

Индексация и срезы в NumPy аналогичны индексации и срезам списков Python, но с расширенными возможностями для многомерных массивов.

arr: np.ndarray = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

element: int = arr[0, 1]  # Доступ к элементу в строке 0, столбце 1 (значение 2)
print(f'{element=}')

subarray: np.ndarray = arr[0:2, 1:3]  # Срез: первые две строки, столбцы с 1 по 2
print(f'{subarray=}')
# Вывод:
# subarray=array([[2, 3],
#       [5, 6]])

Объединение и разделение массивов (concatenate, stack, split)

  • np.concatenate(): Объединяет массивы вдоль указанной оси.
  • np.stack(): Создает новый массив, объединяя массивы вдоль новой оси.
  • np.split(): Разделяет массив на несколько подмассивов.
arr1: np.ndarray = np.array([[1, 2], [3, 4]])
arr2: np.ndarray = np.array([[5, 6], [7, 8]])

concatenated_arr: np.ndarray = np.concatenate((arr1, arr2), axis=0)  # Объединение по строкам
print(f'{concatenated_arr=}')
# concatenated_arr=array([[1, 2],
#       [3, 4],
#       [5, 6],
#       [7, 8]])

stacked_arr: np.ndarray = np.stack((arr1, arr2), axis=0)  # Объединение по новой оси
print(f'{stacked_arr=}')
# stacked_arr=array([[[1, 2],
#        [3, 4]],
#
#       [[5, 6],
#        [7, 8]]])

split_arrs: list[np.ndarray] = np.split(arr1, 2, axis=0)  # Разделение на 2 подмассива по строкам
print(f'{split_arrs=}')
# split_arrs=[array([[1, 2]]), array([[3, 4]])]

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

Арифметические операции: поэлементное сложение, вычитание, умножение, деление

NumPy выполняет арифметические операции поэлементно. Это значит, что операция применяется к каждому элементу массива.

arr1: np.ndarray = np.array([1, 2, 3])
arr2: np.ndarray = np.array([4, 5, 6])

sum_arr: np.ndarray = arr1 + arr2  # Поэлементное сложение
print(f'{sum_arr=}') # sum_arr=array([5, 7, 9])

diff_arr: np.ndarray = arr2 - arr1  # Поэлементное вычитание
print(f'{diff_arr=}') # diff_arr=array([3, 3, 3])

mul_arr: np.ndarray = arr1 * arr2  # Поэлементное умножение
print(f'{mul_arr=}') # mul_arr=array([ 4, 10, 18])

div_arr: np.ndarray = arr2 / arr1  # Поэлементное деление
print(f'{div_arr=}') # div_arr=array([4.        , 2.5       , 2.        ])

Матричные операции: умножение матриц, транспонирование

NumPy предоставляет функции для выполнения матричных операций.

  • np.dot(): Умножение матриц.
  • arr.T: Транспонирование матрицы.
arr1: np.ndarray = np.array([[1, 2], [3, 4]])
arr2: np.ndarray = np.array([[5, 6], [7, 8]])

dot_arr: np.ndarray = np.dot(arr1, arr2)  # Матричное умножение
print(f'{dot_arr=}')
# dot_arr=array([[19, 22],
#       [43, 50]])

transposed_arr: np.ndarray = arr1.T  # Транспонирование
print(f'{transposed_arr=}')
# transposed_arr=array([[1, 3],
#       [2, 4]])

Универсальные функции (ufuncs): применение функций к каждому элементу массива

Универсальные функции (ufuncs) — это функции, которые выполняют поэлементные операции над массивами NumPy. NumPy предоставляет большой набор встроенных ufuncs, таких как np.sin(), np.exp(), np.log() и другие.

arr: np.ndarray = np.array([0, 1, 2, 3])

sin_arr: np.ndarray = np.sin(arr)  # Поэлементный синус
print(f'{sin_arr=}') # sin_arr=array([ 0.        ,  0.84147098,  0.90929743,  0.14112001])

exp_arr: np.ndarray = np.exp(arr)  # Поэлементная экспонента
print(f'{exp_arr=}') # exp_arr=array([ 1.        ,  2.71828183,  7.3890561 , 20.08553692])

Логические операции и маскирование массивов

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

arr: np.ndarray = np.array([1, 2, 3, 4, 5])

mask: np.ndarray = arr > 2  # Создание маски: True для элементов > 2
print(f'{mask=}') # mask=array([False, False,  True,  True,  True])

filtered_arr: np.ndarray = arr[mask]  # Применение маски для выбора элементов
print(f'{filtered_arr=}') # filtered_arr=array([3, 4, 5])

NumPy для статистического анализа данных

Вычисление статистических показателей: среднее, медиана, стандартное отклонение, дисперсия

NumPy предоставляет функции для вычисления основных статистических показателей.

  • np.mean(): Среднее значение.
  • np.median(): Медиана.
  • np.std(): Стандартное отклонение.
  • np.var(): Дисперсия.
data: np.ndarray = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

mean_value: float = np.mean(data)
print(f'{mean_value=}') # mean_value=5.5

median_value: float = np.median(data)
print(f'{median_value=}') # median_value=5.5

std_value: float = np.std(data)
print(f'{std_value=}') # std_value=2.8722813232690143

var_value: float = np.var(data)
print(f'{var_value=}') # var_value=8.25

Работа с пропущенными данными (NaN) в NumPy

NumPy позволяет представлять пропущенные данные с помощью np.nan (Not a Number) и предоставляет функции для работы с ними.

data: np.ndarray = np.array([1, 2, np.nan, 4, 5])

is_nan_mask: np.ndarray = np.isnan(data)  # Создание маски для NaN
print(f'{is_nan_mask=}') # is_nan_mask=array([False, False,  True, False, False])

data_without_nan: np.ndarray = data[~is_nan_mask]  # Удаление NaN
print(f'{data_without_nan=}') # data_without_nan=array([1., 2., 4., 5.])

Сортировка массивов

NumPy предоставляет функции для сортировки массивов.

  • np.sort(): Возвращает отсортированную копию массива.
  • arr.sort(): Сортирует массив на месте.
  • np.argsort(): Возвращает индексы, которые отсортировали бы массив.
data: np.ndarray = np.array([5, 2, 8, 1, 9, 4])

sorted_data: np.ndarray = np.sort(data)  # Сортировка и создание нового массива
print(f'{sorted_data=}') # sorted_data=array([1, 2, 4, 5, 8, 9])

indices: np.ndarray = np.argsort(data)  # Получение индексов отсортированного массива
print(f'{indices=}') # indices=array([3, 1, 5, 0, 2, 4])

NumPy и Pandas: интеграция для эффективного анализа данных

Преобразование данных между NumPy массивами и Pandas DataFrame/Series

Pandas DataFrame и Series могут быть легко преобразованы в NumPy массивы и обратно.

  • df.to_numpy(): Преобразование DataFrame в NumPy массив.
  • pd.DataFrame(arr): Создание DataFrame из NumPy массива.
import pandas as pd

data: dict[str, list[int]] = {'col1': [1, 2, 3], 'col2': [4, 5, 6]}
df: pd.DataFrame = pd.DataFrame(data)

arr: np.ndarray = df.to_numpy()
print(f'{arr=}')
# arr=array([[1, 4],
#       [2, 5],
#       [3, 6]])

df_from_arr: pd.DataFrame = pd.DataFrame(arr, columns=['A', 'B'])
print(f'{df_from_arr=}')
# df_from_arr=   A  B
# 0  1  4
# 1  2  5
# 2  3  6

Использование NumPy для оптимизации операций в Pandas

NumPy может использоваться для оптимизации операций в Pandas, особенно при работе с большими объемами данных. Например, можно применять NumPy-функции напрямую к столбцам DataFrame.

import pandas as pd
import numpy as np

data: dict[str, list[int]] = {'clicks': [100, 150, 200, 120, 180]}
df: pd.DataFrame = pd.DataFrame(data)

# Вместо цикла по DataFrame, применяем NumPy функцию к столбцу
df['clicks_log'] = np.log(df['clicks'])
print(df)
#   clicks  clicks_log
# 0     100    4.605170
# 1     150    5.010635
# 2     200    5.298317
# 3     120    4.787492
# 4     180    5.192957

Примеры анализа данных с использованием NumPy и Pandas в связке

Предположим, у нас есть данные о показах и кликах рекламной кампании в Pandas DataFrame. Мы можем использовать NumPy для вычисления CTR (Click-Through Rate) и других метрик.

import pandas as pd
import numpy as np

data: dict[str, list[int]] = {
    'impressions': [1000, 1500, 2000, 1200, 1800],
    'clicks': [100, 150, 200, 120, 180]
}
df: pd.DataFrame = pd.DataFrame(data)

# Вычисление CTR с использованием NumPy
df['ctr'] = df['clicks'] / df['impressions']

# Вычисление среднего CTR
mean_ctr: float = np.mean(df['ctr'])
print(f'{mean_ctr=}')
print(df)
#    impressions  clicks   ctr
# 0         1000     100  0.10
# 1         1500     150  0.10
# 2         2000     200  0.10
# 3         1200     120  0.10
# 4         1800     180  0.10

Добавить комментарий