Руководство по SciPy: что это, и как ее использовать

Математика — это масса понятий, которые являются одновременно важными и сложными. Для работы с ними в Python есть библиотека SciPy. В этом материале вы познакомитесь с ее функциями на примерах.

Что такое SciPy?

SciPy — это библиотека Python с открытым исходным кодом, предназначенная для решения научных и математических проблем. Она построена на базе NumPy и позволяет управлять данными, а также визуализировать их с помощью разных высокоуровневых команд. Если вы импортируете SciPy, то NumPy отдельно импортировать не нужно.

NumPy vs SciPy

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

Пакеты в SciPy

В SciPy есть набор пакетов для разных научных вычислений:

НазваниеОписание
clusterАлгоритмы кластерного анализа
constantsФизические и математические константы
fftpackБыстрое преобразование Фурье
integrateРешения интегральных и обычных дифференциальных уравнений
interpolateИнтерполяция и сглаживание сплайнов
ioВвод и вывод
linalgЛинейная алгебра
ndimageN-размерная обработка изображений
odrМетод ортогональных расстояний
optimizeОптимизация и численное решение уравнений
signalОбработка сигналов
sparseРазреженные матрицы
spatialРазреженные структуры данных и алгоритмы
specialСпециальные функции
statsСтатистические распределения и функции

Подробное описание можно найти в официальной документации.

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

from scipy import cluster

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

Базовые функции

Взаимодействие с NumPy

SciPy построена на базе NumPy, поэтому можно использовать функции последней для работы с массивами. Чтобы узнать о них подробнее, используйте функции help(), info() или source().

help():

Функция help() подойдет для получения информации о любой функции. Ее можно использовать двумя способами:

  • Без параметров
  • С параметрами

Вот пример для обоих:

from scipy import cluster
help(cluster)               # с параметром
help()                      # без параметра

При исполнении этого кода, первая help() вернет информацию о подмодуле cluster. А вторая — попросит пользователя ввести название модуля, ключевого слова и др., о чем требуется предоставить дополнительную информацию. Для выхода достаточно ввести quit и нажать Enter.

info():

Эта функция возвращает информацию о конкретных функциях, модулях и так далее.

scipy.info(cluster)

source():

Исходный код можно получить только для тех объектов, которые были написаны на Python. Функция не вернет ничего важного, если методы или объекты были написаны, например, на C. Синтаксис простой:

scipy.source(cluster)

Специальные функции

SciPy предоставляет набор специальных функций, используемых в математической физике: эллиптические настраиваемые функции, гамма, бета и так далее. Для их поиска нужно использовать функцию help().

Экспоненциальные и тригонометрические функции

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

Пример:

from scipy import special
a = special.exp10(3)
print(a)
 
b = special.exp2(3)
print(b)
 
c = special.sindg(90)
print(c)
 
d = special.cosdg(45)
print(d)

Вывод:

1000.0
8.0
1.0
0.7071067811865475

Есть и масса других функций из SciPy, с которым стоит познакомиться.

Интегральные функции

Есть и функции для решения интегралов. В их числе как обычные дифференциальные интеграторы, так и методы трапеций.

В SciPy представлена функция quad, которая занимается вычислением интеграла функции с одной переменной. Границы могут быть ±∞ (±inf) для обозначения бесконечных пределов. Синтаксис этой функции следующий:

quad(func, a, b, args=(), full_output=0, epsabs=1.49e-08, 
epsrel=1.49e-08, limit=50, points=None, weight=None, 
wvar=None, wopts=None, maxp1=50, limlst=50)

А здесь она внедрена в пределах a и b (могут быть бесконечностями).

from scipy import special
from scipy import integrate
a = lambda x:special.exp10(x)
b = scipy.integrate.quad(a, 0, 1)
print(b)

В этом примере функция a находится в пределах 0 и 1. После выполнения вывод будет такой:

(3.9086503371292665, 4.3394735994897923e-14)

Двойные интегральные функции

SciPy включает также и dblquad, которая используется для вычисления двойных интегралов. Двойной интеграл, как известно, состоит из двух реальных переменных. Функция dblquad() принимает функцию, которую нужно интегрировать, в качестве параметра, а также 4 переменных: две границы и функции dy и dx.

Пример:

from scipy import integrate
a = lambda y, x: x*y**2
b = lambda x: 1
c = lambda x: -1
integrate.dblquad(a, 0, 2, b, c)

Вывод:

(-1.3333333333333335, 1.4802973661668755e-14)

В SciPy есть другие функции для вычисления тройных интегралов, n интегралов, интегралов Ромберга и других. О них можно узнать подробнее с помощью help.

Функции оптимизации

В scipy.optimize есть часто используемые алгоритмы оптимизации:


  • Неограниченная и ограниченная минимизация многомерных скалярных функций, то есть minimize (например, Алгоритм Бройдена — Флетчера — Гольдфарба — Шанно, метод сопряженных градиентов, метод Нелдера — Мида и так далее)
  • Глобальная оптимизация (дифференциальная эволюция, двойной отжиг и т. д.)
  • Минимизация наименьших квадратов и подбор кривой (метод наименьших квадратов, приближение с помощью кривых и т. д.)
  • Минимизаторы скалярных одномерных функций и численное решение уравнений (минимизация скаляра и скаляр корня)
  • Решатели систем многомерных уравнений с помощью таких алгоритмов, как Пауэлла, Левендберга — Марквардта.

Функция Розенброка

Функция Розенброка (rosen) — это тестовая проблема для оптимизационных алгоритмов, основанных на градиентах. В SciPy она определена следующим образом:

sum(100.0*(x[1:] - x[:-1]**2.0)**2.0 + (1 - x[+-1])**2.0)

Пример:

import numpy as np
from scipy.optimize import rosen
a = 1.2 * np.arange(5)
rosen(a)

Вывод:

7371.0399999999945

Nelder-Mead

Это числовой метод, который часто используется для поиска минимума/максимума функции в многомерном пространстве. В следующем примере метод использован вместе с алгоритмом Нелдера — Мида.

Пример:

from scipy import optimize
a = [2.4, 1.7, 3.1, 2.9, 0.2]
b = optimize.minimize(optimize.rosen, a, method='Nelder-Mead')
b.x

Вывод:

array([0.96570182, 0.93255069, 0.86939478, 0.75497872, 0.56793357])

Функции интерполяции

В сфере числового анализа интерполяция — это построение новых точек данных на основе известных. Библиотека SciPy включает подпакет scipy.interpolate, состоящий из сплайновых функций и классов, одно- и многомерных интерполяционных классов и так далее.

Одномерная интерполяция

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

Пример:

import matplotlib.pyplot as plt
from scipy import interpolate
x = np.arange(5, 20)
y = np.exp(x/3.0)
f = interpolate.interp1d(x, y)x1 = np.arange(6, 12)
y1 = f(x1)   # использовать функцию интерполяции, возвращаемую `interp1d`
plt.plot(x, y, 'o', x1, y1, '--')
plt.show()

Вывод:
Одномерная интерполяция scipy

Многомерная интерполяция

Многомерная интерполяция (пространственная интерполяция) — это тип интерполяции функций, который состоит из более чем одной переменной. Следующий пример демонстрирует работу функции interp2a.

При интерполяции на двумерную сетку функция использует массивы x, y и z для приближения функции f: "z = f(x, y)" и возвращает функцию, у которой вызываемый метод использует сплайновую интерполяцию для поиска значения новых точек.

Пример:

from scipy import interpolate
import matplotlib.pyplot as plt
x = np.arange(0,10)
y = np.arange(10,25)
x1, y1 = np.meshgrid(x, y)
z = np.tan(xx+yy)
f = interpolate.interp2d(x, y, z, kind='cubic')
x2 = np.arange(2,8)
y2 = np.arange(15,20)
z2 = f(xnew, ynew)
plt.plot(x, z[0, :], 'ro-', x2, z2[0, :], '--')
plt.show()

Вывод:
Многомерная интерполяция scipy

Функции преобразования Фурье

Анализ Фурье — это метод, который помогает представлять функцию в виде суммы периодических компонентов и восстанавливать сигнал из них. Функции fft используются для получения дискретной трансформации Фурье реальной или комплексной последовательности.

Пример:

from scipy.fftpack import fft, ifft
x = np.array([0,1,2,3])
y = fft(x)
print(y)

Вывод:


[6.+0.j -2.+2.j -2.+0.j -2.-2.j]

Похожим образом можно найти обратное значение с помощью функции ifft.

Пример:

rom scipy.fftpack import fft, ifft
x = np.array([0,1,2,3])
y = ifft(x)
print(y)

Вывод:

[1.5+0.j -0.5-0.5j -0.5+0.j -0.5+0.5j]

Функции обработки сигналов

Обработка сигналов — это область анализа, модификации и синтеза сигналов: звуков, изображений и т. д. SciPy предоставляет некоторые функции, с помощью которых можно проектировать, фильтровать и интерполировать одномерные и двумерные данные.

Фильтрация:

Фильтруя сигнал, можно удалить нежелаемые составляющие. Для выполнения упорядоченной фильтрации используется функция order_filter. Она выполняет операцию на массиве. Синтаксис следующий:

order_filter(a, domain, rank)

a — N-мерный массив с входящими данными

domain — массив масок с тем же количеством размерностей, что и у массива a

rank — неотрицательное число, которое выбирает элементы из отсортированного списка (0, 1…)

Пример:

from scipy import signal
x = np.arange(35).reshape(7, 5)
domain = np.identity(3)
print(x,end='nn')
print(signal.order_filter(x, domain, 1))

Вывод:

[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]
[25 26 27 28 29]
[30 31 32 33 34]]

[[ 0. 1. 2. 3. 0.]
[ 5. 6. 7. 8. 3.]
[10. 11. 12. 13. 8.]
[15. 16. 17. 18. 13.]
[20. 21. 22. 23. 18.]
[25. 26. 27. 28. 23.]
[ 0. 25. 26. 27. 28.]]

Сигналы

Подпакет scipy.signal также состоит из функций, с помощью которых можно генерировать сигналы. Одна из таких — chirp. Она является генератором частотно-модулированного сигнала, а ее синтаксис следующий:

chirp(t, f0, t1, f1, method='linear', phi=0, vertex_zero=True)

Пример:

from scipy.signal import chirp, spectrogram
import matplotlib.pyplot as plt
t = np.linspace(6, 10, 500)
w = chirp(t, f0=4, f1=2, t1=5, method='linear')
plt.plot(t, w)
plt.title("Linear Chirp")
plt.xlabel('time in sec)')
plt.show()

Вывод:
Сигналы scipy

Линейная алгебра

Линейная алгебра работает с линейными уравнениями и их представлениями с помощью векторных пространств и матриц. SciPy построена на базе библиотек ATLAS LAPACK и BLAS и является очень быстрой в сфере решения проблем, связанных с линейной алгеброй. В дополнение к функциям из numpy.linalg scipy.linalg также предоставляет набор продвинутых функций. Если numpy.linalg не используется вместе с ATLAS LAPACK и BLAS, то scipy.linalg работает намного быстрее.

Нахождение обратной матрицы

С математической точки зрения обратная матрица A — это матрица B, где AB = I, а I — это единичная матрица, состоящая из единиц по диагонали. Это можно обозначить как B=A-1. В SciPy такого можно добиться с помощью метода linalg.inv.

Пример:

import numpy as np
from scipy import linalg
A = np.array([[1,2], [4,3]])
B = linalg.inv(A)
print(B)

Вывод:

[[-0.6 0.4]
[ 0.8 -0.2]]

Нахождение определителей

Значение, полученное арифметическим путем из коэффициентов матрицы является определителем квадратной матрицы. В SciPy это делается с помощью функции det с таким синтаксисом:

det(a, overwrite_a=False, check_finite=True)

a — (M, M) — это квадратная матрица

overwrite_a(bool, optional) — разрешает перезаписывать данные


check_finite(bool, optional) — для проверки состоит ли матрица только из конечных чисел

Пример:

import numpy as np
from scipy import linalg
A = np.array([[1,2], [4,3]])
B = linalg.det(A)
print(B)

Вывод:

-5.0

Разреженные собственные значения

Разреженные собственные значения — это набор скаляров, связанных с линейными уравнениями. ARPACK предоставляет способ быстрого нахождения этих значений (собственных векторов). Вся функциональность скрыта в двух интерфейсах: scipy.sparse.linalg.eigs и scipy.sparse.linalg.eigsh.

Интерфейс eigs позволяет находить собственные значения реальных или комплексных несимметричных квадратных матриц, а eigsh содержит интерфейсы реальных симметричных или комплексных Эрмитовых матриц.

Функция eigh решает обобщенную проблему собственного значения для комплексной Эрмитовой или реально симметричной матрицы

Пример:

from scipy.linalg import eigh
import numpy as np
A = np.array([[1, 2, 3, 4], [4, 3, 2, 1], [1, 4, 6, 3], [2, 3, 2, 5]])
a, b = eigh(A)
print("Selected eigenvalues :", a)
print("Complex ndarray :", b)

Вывод:

Selected eigenvalues : [-2.53382695 1.66735639 3.69488657 12.17158399]
Complex ndarray : [[ 0.69205614 0.5829305 0.25682823 -0.33954321]
[-0.68277875 0.46838936 0.03700454 -0.5595134 ]
[ 0.23275694 -0.29164622 -0.72710245 -0.57627139]
[ 0.02637572 -0.59644441 0.63560361 -0.48945525]]

Разреженные структуры данных и алгоритмы

Разреженные данные состоят из объектов, которые в свою очередь состоят из линий, точек, поверхностей и так далее. Пакет scipy.spatial из SciPy может вычислять диаграммы Вороного, триангуляцию и другое с помощью библиотеки Qhull. Он также включает реализации KDTree для точечных запросов ближайших соседей.

Триангуляции Делоне

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

Пример:

import matplotlib.pyplot as plt
from scipy.spatial import Delaunay
points = np.array([[0, 1], [1, 1], [1, 0],[0, 0]])
a = Delaunay(points)       # Объект Делоне
print(a)
print(a.simplices)
plt.triplot(points[:,0], points[:,1], a.simplices)
plt.plot(points[:,1], points[:,0], 'o')
plt.show()

Вывод:
Триангуляции Делоне scipy

Функции многомерной обработки изображений

Обработка изображений — это выполнение операций над изображением по получению информации или улучшенной копии этого изображения из оригинала. Пакет scipy.ndimage состоит из нескольких функций обработки и анализа изображений, которые нужны для работы с массивами с произвольной размерностью.

Свертка и корреляция

В SciPy есть несколько функций для свертки и корреляции изображений.

  • Функция correlate1d используется для вычисления одномерной корреляции по заданной оси
  • Функция correlate предлагает многомерную корреляцию для любого массива с определенным ядром
  • Функция convolve1d используется для вычисления одномерной свертки вдоль заданной оси
  • Функция convolve предлагает многомерную свертку для любого массива с определенным ядром

Пример:

import numpy as np
from scipy.ndimage import correlate1d
correlate1d([3,5,1,7,2,6,9,4], weights=[1,2])

Вывод:

array([ 9, 13, 7, 15, 11, 14, 24, 17])

Файловый ввод/вывод

Пакет scipy.io предоставляет несколько функций, которые помогают управлять файлами в разных форматах, включая MATLAB, файлы IDL, Matrix Market и другие.

Для использования его нужно сначала импортировать:

import scipy.io as sio

Подробная информация есть в официальной документации.