SciPy-стек: NumPy, SciPy, SymPy, Matplotlib, pandas
Пять китов научного Python: какую роль играет каждая библиотека и где проходят границы между ними.
SciPy-стек — устоявшийся набор взаимодополняющих библиотек: NumPy, SciPy, SymPy, Matplotlib, pandas (плюс IPython/Jupyter как среда).
Кто за что отвечает
Главная ошибка новичка — не понимать, какой инструмент брать под задачу. Запомните разделение труда:
| Библиотека | Зона ответственности | Ключевой объект |
| NumPy | Многомерные массивы и быстрая арифметика над ними | ndarray |
| SciPy | Готовые научные алгоритмы поверх NumPy (интегралы, оптимизация, статистика…) | функции в подмодулях |
| SymPy | Символьная (точная) математика: формулы, производные, решение уравнений | Symbol, Expr |
| Matplotlib | Построение графиков и научная визуализация | Figure, Axes |
| pandas | Табличные данные с метками: загрузка, очистка, агрегация | DataFrame |
Как они складываются в пирамиду
Стек не плоский — это слои, где верхние опираются на нижние:
┌─────────────────────────────────────┐
│ Jupyter / IPython (среда работы) │
├──────────────┬──────────────┬───────┤
│ SciPy │ pandas │ Matplotlib
│ (алгоритмы) │ (таблицы) │ (графики)
├──────────────┴──────────────┴───────┤
│ NumPy (ndarray) │ <- общий фундамент
├─────────────────────────────────────┤
│ Python + C/Fortran │
└─────────────────────────────────────┘
SymPy стоит "сбоку": работает с формулами,
а не с числами, но умеет отдавать результат
вниз в NumPy через lambdify.
NumPy — фундамент: и SciPy, и pandas, и Matplotlib хранят данные в ndarray. SymPy стоит особняком: он про точные символы, но через мост lambdify отдаёт готовую формулу в численный мир NumPy.
Один пример — пять ролей
Допустим, мы измерили зависимость и хотим её обработать. Каждая библиотека возьмёт свой кусок (псевдокод, поэтому он помечен как текст):
import pandas as pd # 1. pandas: читаем таблицу измерений
df = pd.read_csv("data.csv")
import numpy as np # 2. numpy: достаём столбцы как массивы
x = df["t"].to_numpy()
y = df["value"].to_numpy()
from scipy.optimize import curve_fit # 3. scipy: подгоняем модель
params, _ = curve_fit(lambda t, a, b: a*np.exp(-b*t), x, y)
import sympy as sp # 4. sympy: символьно выводим производную модели
t, a, b = sp.symbols("t a b")
print(sp.diff(a*sp.exp(-b*t), t)) # -a*b*exp(-b*t)
import matplotlib.pyplot as plt # 5. matplotlib: рисуем результат
plt.plot(x, y, "o"); plt.show()
Видно: pandas достаёт данные, NumPy держит их в массивах, SciPy подгоняет, SymPy выводит формулу, Matplotlib рисует. Каждый — на своём месте.
А «руками» это выглядит так
Чтобы почувствовать, что под капотом нет магии, посчитаем среднее и стандартное отклонение списка чисел на чистом stdlib (модуль statistics) — то, что pandas/NumPy делают «из коробки»:
import statistics
data = [2.1, 2.5, 2.0, 2.8, 2.4, 2.6]
print("Среднее:", round(statistics.mean(data), 4))
print("Ст. откл.:", round(statistics.pstdev(data), 4))
print("Медиана:", statistics.median(data))
Вывод:
Среднее: 2.4 Ст. откл.: 0.2769 Медиана: 2.45
Как работает под капотом
Почему стек именно такой? Исторически NumPy родился из слияния двух более ранних пакетов (Numeric и numarray) — нужен был единый тип массива, иначе библиотеки не могли обмениваться данными. Как только появился общий ndarray, всё остальное смогло на него опереться: SciPy перестал изобретать своё хранилище, Matplotlib стал принимать массивы напрямую. Это пример силы стандарта: согласованный формат данных важнее, чем любая отдельная фича.
Частые ошибки
- Тащить SciPy туда, где хватит NumPy. Перемножить матрицы или взять среднее — это NumPy; SciPy нужен для алгоритмов (интегралы, оптимизация).
- Считать pandas «таблицей Excel». Под капотом это NumPy-массивы с метками; для тяжёлой математики работают с
.to_numpy(). - Смешивать символьное и численное. Объект SymPy нельзя сунуть в NumPy напрямую — нужен мост
lambdify(о нём — позже).
Итог
- NumPy — массивы, SciPy — алгоритмы, SymPy — символика, Matplotlib — графики, pandas — таблицы.
- NumPy — общий фундамент стека; всё остальное опирается на его
ndarray. - SymPy стоит сбоку (точная математика) и связывается с численным миром через
lambdify. - Под задачу берите правильный слой: не пушку по воробьям и не наоборот.