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

Что такое NumPy и зачем он нужен?

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

Установка и настройка NumPy

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

pip install numpy

Также можно использовать conda, если вы используете дистрибутив Anaconda:

conda install numpy

Импорт библиотеки NumPy

Для использования NumPy в Python-скрипте необходимо импортировать библиотеку. Обычно используют сокращенное имя np:

import numpy as np

Основные объекты NumPy: Массивы

Создание массивов NumPy (ndarray)

Основным объектом NumPy является ndarray (n-dimensional array) — многомерный массив однородных данных. Вот несколько способов создания массивов:

  • Из списка Python:

    import numpy as np
    
    my_list = [1, 2, 3, 4, 5]
    arr = np.array(my_list)
    print(arr)  # Output: [1 2 3 4 5]
    
  • С использованием функций zeros, ones, empty, full:

    import numpy as np
    
    zeros_arr = np.zeros((2, 3))  # Массив 2x3, заполненный нулями
    ones_arr = np.ones((3, 2))   # Массив 3x2, заполненный единицами
    empty_arr = np.empty((2, 2))  # Массив 2x2, заполненный случайными значениями (не инициализирован)
    full_arr = np.full((2, 2), 7) # Массив 2x2, заполненный значением 7
    identity_matrix = np.eye(3) # Единичная матрица 3x3
    
    print(zeros_arr)
    print(ones_arr)
    print(empty_arr)
    print(full_arr)
    print(identity_matrix)
    
  • С использованием функций arange, linspace:

    import numpy as np
    
    arange_arr = np.arange(0, 10, 2)  # Массив от 0 до 10 (не включая), с шагом 2
    linspace_arr = np.linspace(0, 1, 5)  # Массив из 5 равномерно распределенных чисел от 0 до 1
    
    print(arange_arr)
    print(linspace_arr)
    

Типы данных в массивах NumPy (dtype)

Каждый массив NumPy имеет определенный тип данных (dtype). Важно выбирать правильный тип данных для эффективного использования памяти и точности вычислений. Некоторые распространенные типы данных:

  • int8, int16, int32, int64: Целые числа разной разрядности.
  • uint8, uint16, uint32, uint64: Беззнаковые целые числа.
  • float16, float32, float64: Числа с плавающей точкой разной точности.
  • bool: Логические значения (True или False).
  • string_, unicode_: Строки.
import numpy as np

arr = np.array([1, 2, 3], dtype=np.int32)
print(arr.dtype)  # Output: int32

arr_float = arr.astype(np.float64)
print(arr_float.dtype) # Output: float64

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

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

import numpy as np

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

print(arr[0, 0])  # Output: 1 (элемент в первой строке и первом столбце)
print(arr[1, :])  # Output: [4 5 6] (вторая строка)
print(arr[:, 2])  # Output: [3 6 9] (третий столбец)
print(arr[0:2, 1:3])  # Output: [[2 3]
                     #          [5 6]] (срез)

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

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

import numpy as np

arr = np.arange(12)
reshaped_arr = arr.reshape(3, 4)
print(reshaped_arr)
# Output:
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]]

flattened_arr = reshaped_arr.flatten() # Преобразование в одномерный массив
print(flattened_arr)
# Output: [ 0  1  2  3  4  5  6  7  8  9 10 11]

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

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

NumPy позволяет выполнять арифметические операции между массивами поэлементно. Важно, чтобы формы массивов были совместимы (broadcasting).

import numpy as np

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

print(arr1 + arr2)  # Output: [5 7 9]
print(arr1 * arr2)  # Output: [ 4 10 18]
print(arr1 - arr2)  # Output: [-3 -3 -3]
print(arr1 / arr2)  # Output: [0.25 0.4  0.5 ]
print(arr1 ** 2)   # Output: [1 4 9]

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

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

import numpy as np

matrix1 = np.array([[1, 2], [3, 4]])
matrix2 = np.array([[5, 6], [7, 8]])

product = np.dot(matrix1, matrix2)  # Умножение матриц
transposed_matrix = matrix1.T  # Транспонирование

print(product)
# Output:
# [[19 22]
#  [43 50]]

print(transposed_matrix)
# Output:
# [[1 3]
#  [2 4]]

Универсальные функции (ufunc): математические, тригонометрические, и другие

Универсальные функции (ufunc) — это функции, которые применяются к каждому элементу массива. NumPy предоставляет широкий набор ufunc:

  • np.sin, np.cos, np.tan: Тригонометрические функции.
  • np.exp, np.log, np.sqrt: Экспонента, логарифм, квадратный корень.
  • np.abs, np.round, np.floor, np.ceil: Абсолютное значение, округление.
import numpy as np

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

sin_arr = np.sin(arr)
log_arr = np.log(arr + 1) # Добавляем 1, чтобы избежать логарифма нуля

print(sin_arr)
print(log_arr)

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

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

import numpy as np

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

mask = arr > 2
print(mask)  # Output: [False False  True  True  True]

filtered_arr = arr[mask]  # Выбор элементов, удовлетворяющих условию
print(filtered_arr)  # Output: [3 4 5]

where_arr = np.where(arr > 2, arr * 2, arr) # Если элемент > 2, умножаем на 2, иначе оставляем как есть
print(where_arr) # Output: [1 2 6 8 10]

Эффективная работа с данными в NumPy

Векторизация операций: избегаем циклов Python

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

Пример: Рассмотрим задачу увеличения каждого элемента массива на 1.

  • С использованием цикла Python (медленно):

    import numpy as np
    
    def add_one_loop(arr):
        result = np.zeros_like(arr)
        for i in range(len(arr)):
            result[i] = arr[i] + 1
        return result
    
    arr = np.arange(1000000)
    result = add_one_loop(arr)
    
  • С использованием векторизации NumPy (быстро):

    import numpy as np
    
    def add_one_vectorized(arr):
        return arr + 1
    
    arr = np.arange(1000000)
    result = add_one_vectorized(arr)
    

Второй вариант будет работать значительно быстрее, особенно для больших массивов.

Broadcasting: правила и примеры

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

Правила Broadcasting:

  1. Если массивы имеют разное количество измерений, к массиву с меньшим числом измерений добавляются единичные измерения слева.
  2. Если форма массивов не совпадает в каком-то измерении, массив с формой 1 в этом измерении растягивается до формы другого массива.
  3. Если ни одно из правил не выполняется, возникает ошибка.

Пример:

import numpy as np

arr1 = np.array([1, 2, 3])
arr2 = 5  # Скаляр

print(arr1 + arr2)  # Output: [6 7 8] (скаляр растягивается до формы arr1)

arr3 = np.array([[1, 2, 3], [4, 5, 6]])
arr4 = np.array([10, 20, 30])

print(arr3 + arr4)
# Output:
# [[11 22 33]
#  [14 25 36]] (arr4 растягивается до формы arr3)

Использование NumPy для работы с большими данными

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

NumPy и анализ данных

Статистические функции NumPy (среднее, медиана, стандартное отклонение)

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

import numpy as np

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

mean = np.mean(arr)  # Среднее значение
median = np.median(arr)  # Медиана
std = np.std(arr)  # Стандартное отклонение

print(f'Mean: {mean}, Median: {median}, Standard Deviation: {std}')

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

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

import numpy as np

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

sorted_arr = np.sort(arr)  # Сортировка массива (возвращает отсортированную копию)
print(sorted_arr) # Output: [1 2 3 4 5]

arr.sort()  # Сортировка массива на месте (изменяет исходный массив)
print(arr) # Output: [1 2 3 4 5]

indices = np.argsort(arr) # Индексы, которые отсортировали бы массив
print(indices) # Output: [0 1 2 3 4]


index = np.argmax(arr) # Индекс максимального элемента
print(index)

NumPy и Pandas: интеграция и совместное использование

Pandas — это библиотека для анализа данных, построенная на основе NumPy. Pandas использует NumPy для хранения и обработки данных, и предлагает более высокоуровневые инструменты для работы с табличными данными (DataFrames). DataFrame может содержать данные разных типов (числа, строки, даты и т.д.). NumPy массивы можно легко преобразовывать в DataFrame и наоборот.

import numpy as np
import pandas as pd

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

df = pd.DataFrame(arr, columns=['A', 'B', 'C'])
print(df)

# Output:
#    A  B  C
# 0  1  2  3
# 1  4  5  6

numpy_array = df.to_numpy()
print(numpy_array)

# Output:
# [[1 2 3]
#  [4 5 6]]

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


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