| name | scipy |
| description | python library |
| version | 1.17.1 |
| ecosystem | python |
| license | BSD-3-Clause |
| generated_with | claude-sonnet-4-5-20250929 |
Imports
import scipy
import numpy as np
from scipy import sparse
from scipy.sparse import coo_array, csr_array, csc_array, bsr_array
from scipy.sparse import dia_array, dok_array, lil_array
from scipy.sparse import linalg as splinalg
from scipy.sparse import csgraph
from scipy import fft
from scipy.fft import fft, ifft, fft2, ifft2
from scipy import optimize
from scipy.optimize import minimize, differential_evolution
from scipy import linalg
from scipy import signal
from scipy import stats
from scipy import integrate
from scipy import interpolate
from scipy import ndimage
from scipy import special
from scipy import odr
from scipy.odr import Data, RealData, Model, ODR
from scipy.odr import multilinear, exponential, polynomial, unilinear, quadratic
from scipy import spatial
from scipy import constants
from scipy import io
from scipy import cluster
from scipy import datasets
from scipy import differentiate
Core Concepts
Subpackages
SciPy is organized into subpackages, each focused on a specific domain:
- cluster: Clustering algorithms (k-means, hierarchical)
- constants: Physical and mathematical constants
- datasets: Example datasets for testing
- differentiate: Finite difference differentiation
- fft: Fast Fourier Transform algorithms
- integrate: Integration and ODE solvers
- interpolate: Interpolation and smoothing
- io: Data input/output (MATLAB, WAV, etc.)
- linalg: Linear algebra routines
- ndimage: N-dimensional image processing
- odr: Orthogonal Distance Regression
- optimize: Optimization and root finding
- signal: Signal processing
- sparse: Sparse matrix support
- spatial: Spatial data structures and algorithms
- special: Special mathematical functions
- stats: Statistical functions and distributions
Lazy Loading
SciPy uses lazy loading - submodules are imported only when first accessed to reduce startup time.
Core Patterns
Sparse Matrix Workflow
from scipy import sparse
import numpy as np
row = np.array([0, 1, 2, 0])
col = np.array([0, 1, 2, 2])
data = np.array([1, 2, 3, 4])
coo = sparse.coo_array((data, (row, col)), shape=(3, 3))
csr = coo.tocsr()
csr.sum_duplicates()
csr.eliminate_zeros()
result = csr @ csr.T
Optimization Workflow
from scipy import optimize
def objective(x):
return (x[0] - 1)**2 + (x[1] - 2.5)**2
def constraint(x):
return x[0] + x[1] - 2
x0 = [0, 0]
cons = {'type': 'ineq', 'fun': constraint}
bounds = [(0, None), (0, None)]
result = optimize.minimize(objective, x0,
method='SLSQP',
constraints=cons,
bounds=bounds)
if result.success:
print(f"Solution: {result.x}")
ODR Workflow
from scipy import odr
import numpy as np
def model_func(B, x):
return B[0] * x + B[1]
x = np.array([1, 2, 3, 4, 5])
y = np.array([2.1, 3.9, 6.2, 7.8, 10.1])
sx = np.array([0.1, 0.1, 0.1, 0.1, 0.1])
sy = np.array([0.2, 0.2, 0.2, 0.2, 0.2])
data = odr.RealData(x, y, sx=sx, sy=sy)
model = odr.Model(model_func)
odr_obj = odr.ODR(data, model, beta0=[1., 0.])
output = odr_obj.run()
output.pprint()
print(f"Chi-square: {output.res_var}")
Iterative Solver Pattern
from scipy.sparse import linalg as splinalg
from scipy import sparse
import numpy as np
A = sparse.csr_array([[3, 0, 1], [0, 4, 0], [1, 0, 2]])
b = np.array([1, 2, 3])
M = sparse.diags(1.0 / A.diagonal())
def callback(xk):
print(f"Residual: {np.linalg.norm(A @ xk - b)}")
x, info = splinalg.cg(A, b, M=M, callback=callback, tol=1e-5)
if info == 0:
print("Converged successfully")
elif info > 0:
print(f"Converged after {info} iterations")
else:
print("Failed to converge")
Signal Processing Pipeline
from scipy import signal
import numpy as np
fs = 1000
b, a = signal.butter(4, [10, 100], btype='band', fs=fs)
data = np.random.randn(10000)
filtered = signal.filtfilt(b, a, data)
f, Pxx = signal.welch(filtered, fs=fs)
peaks, _ = signal.find_peaks(Pxx, height=0.1)
Sparse Matrices
Creating Sparse Arrays
import numpy as np
from scipy import sparse
row = np.array([0, 1, 2, 0])
col = np.array([0, 1, 2, 2])
data = np.array([1, 2, 3, 4])
coo = sparse.coo_array((data, (row, col)), shape=(3, 3))
csr = sparse.csr_array([[1, 0, 2], [0, 3, 0]])
csc = sparse.csc_array([[1, 0, 2], [0, 3, 0]])
dok = sparse.dok_array((5, 5))
dok[0, 0] = 1
dok[1, 2] = 2
lil = sparse.lil_array((10, 10))
lil[0, :5] = 1
lil[1, 5:] = 2
dense = np.eye()
sparse_eye = sparse.csr_array(dense)
Format Conversion
coo = sparse.coo_array([[1, 0], [0, 2]])
csr = coo.tocsr()
csc = coo.tocsc()
dense = coo.toarray()
Sparse Array Operations
from scipy import sparse
import numpy as np
a = sparse.csr_array([[1, 0, 2], [0, 3, 0]])
b = sparse.csr_array([[0, 1], [2, 0], [0, 3]])
c = a @ b
doubled = a * 2
added = a + a
total = a.sum()
row_max = a.max(axis=1)
col_mean = a.mean(axis=0)
element = a[0, 2]
row = a[1, :]
submatrix = a[:2, :2]
a.eliminate_zeros()
a.sum_duplicates()
Sparse Linear Algebra
from scipy.sparse import linalg as splinalg
from scipy import sparse
import numpy as np
A = sparse.csr_array([[3, 0, 1], [0, 4, 0], [1, 0, 2]])
b = np.array([1, 2, 3])
x = splinalg.spsolve(A, b)
x, info = splinalg.cg(A, b)
x, info = splinalg.gmres(A, b)
eigenvalues, eigenvectors = splinalg.eigs(A, k=2)
norm = splinalg.norm(A)
Sparse Graph Algorithms
from scipy.sparse import csgraph
from scipy import sparse
import numpy as np
graph = sparse.csr_array([
[0, 1, 2, 0],
[1, 0, 0, 1],
[2, 0, 0, 3],
[0, 1, 3, 0]
])
dist_matrix = csgraph.dijkstra(graph, indices=0)
all_pairs = csgraph.floyd_warshall(graph)
mst = csgraph.minimum_spanning_tree(graph)
n_components, labels = csgraph.connected_components(graph)
bfs_tree = csgraph.breadth_first_tree(graph, 0)
dfs_tree = csgraph.depth_first_tree(graph, 0)
Fast Fourier Transform
from scipy import fft
import numpy as np
x = np.array([1.0, 2.0, 1.0, -1.0, 1.5])
y = fft.fft(x)
x_recovered = fft.ifft(y)
y = fft.rfft(x)
x_recovered = fft.irfft(y)
image = np.random.rand(100, 100)
freq = fft.fft2(image)
image_recovered = fft.ifft2(freq)
freq_shifted = fft.fftshift(freq)
freq_unshifted = fft.ifftshift(freq_shifted)
freqs = fft.fftfreq(len(x), d=0.1)
Optimization
Minimization
from scipy import optimize
import numpy as np
def rosenbrock(x):
return sum(100.0 * (x[1:] - x[:-1]**2)**2 + (1 - x[:-1])**2)
x0 = np.array([1.3, 0.7, 0.8, 1.9, 1.2])
result = optimize.minimize(rosenbrock, x0, method='BFGS')
print(result.x, result.fun)
def constraint(x):
return x[0] + x[1] - 1
cons = {'type': 'eq', 'fun': constraint}
result = optimize.minimize(rosenbrock, x0, method='SLSQP', constraints=cons)
bounds = [(0, None), (0, None), (0, None), (0, None), (0, None)]
result = optimize.minimize(rosenbrock, x0, method='L-BFGS-B', bounds=bounds)
Global Optimization
from scipy.optimize import differential_evolution
import numpy as np
def objective(x):
return x[0]**2 + x[1]**2
bounds = [(-5, 5), (-5, 5)]
result = differential_evolution(objective, bounds)
print(result.x, result.fun)
result = differential_evolution(
objective,
bounds,
strategy='best1bin',
maxiter=1000,
popsize=15,
tol=0.01,
mutation=(0.5, 1),
recombination=0.7,
workers=4
)
Root Finding
from scipy import optimize
def f(x):
return x**3 - 1
root = optimize.brentq(f, -2, 2)
root = optimize.newton(f, x0=0.5)
def equations(vars):
x, y = vars
return [x**2 + y**2 - 1, x - y]
solution = optimize.fsolve(equations, [1, 1])
Curve Fitting
from scipy import optimize
import numpy as np
xdata = np.array([0, 1, 2, 3, 4])
ydata = np.array([1, 3, 5, 7, 9])
def model(x, a, b):
return a * x + b
params, cov = optimize.curve_fit(model, xdata, ydata)
print(f"a={params[0]}, b={params[1]}")
Orthogonal Distance Regression
ODR fits models to data with errors in both x and y coordinates.
Basic ODR Usage
from scipy import odr
import numpy as np
def linear_func(B, x):
return B[0] * x + B[1]
x = np.array([0., 1., 2., 3., 4., 5.])
y = np.array([1.2, 2.9, 5.1, 6.8, 8.9, 11.2])
data = odr.Data(x, y)
model = odr.Model(linear_func)
odr_obj = odr.ODR(data, model, beta0=[1., 0.])
output = odr_obj.run()
print(f"Fitted parameters: {output.beta}")
print(f"Standard errors: {output.sd_beta}")
print(f"Covariance: {output.cov_beta}")
ODR with Measurement Errors
from scipy import odr
import numpy as np
x = np.array([0., 0.9, 1.8, 2.6, 3.3, 4.4, 5.2, 6.1, 6.5, 7.4])
y = np.array([5.9, 5.4, 4.4, 4.6, 3.5, 3.7, 2.8, 2.8, 2.4, 1.5])
x_err = np.array([0.03, 0.03, 0.04, 0.035, 0.07, 0.11, 0.13, 0.22, 0.74, 1.])
y_err = np.array([1., 0.74, 0.5, 0.35, 0.22, 0.22, 0.12, 0.12, 0.1, 0.04])
def func(B, x):
return B[0] * x + B[1]
data = odr.RealData(x, y, sx=x_err, sy=y_err)
model = odr.Model(func)
odr_obj = odr.ODR(data, model, beta0=[0., 1.])
output = odr_obj.run()
output.pprint()
Built-in ODR Models
from scipy import odr
import numpy as np
x = np.linspace(0.0, 5.0)
y = 10.0 + 5.0 * x
data = odr.Data(x, y)
odr_obj = odr.ODR(data, odr.multilinear)
output = odr_obj.run()
print(f"Linear fit: {output.beta}")
y = -10.0 + np.exp(0.5 * x)
data = odr.Data(x, y)
odr_obj = odr.ODR(data, odr.exponential)
output = odr_obj.run()
print(f"Exponential fit: {output.beta}")
y = 1.0 * x**2 + 2.0 * x + 3.0
data = odr.Data(x, y)
odr_obj = odr.ODR(data, odr.quadratic)
output = odr_obj.run()
print(f"Quadratic fit: {output.beta}")
y = 1.0 + 2.0 * x + 3.0 * x**2 + 4.0 * x**3
poly_model = odr.polynomial(3)
data = odr.Data(x, y)
odr_obj = odr.ODR(data, poly_model)
output = odr_obj.run()
print(f"Polynomial fit: {output.beta}")
Advanced ODR Features
from scipy import odr
import numpy as np
def func(B, x):
return B[0] + B[1] * np.power(np.exp(B[2]*x) - 1.0, 2)
def fjacb(B, x):
"""Jacobian with respect to parameters"""
eBx = np.exp(B[2]*x)
return np.vstack([
np.ones(x.shape[-1]),
np.power(eBx - 1.0, 2),
B[1] * 2.0 * (eBx - 1.0) * eBx * x
])
def fjacd(B, x):
"""Jacobian with respect to data"""
eBx = np.exp(B[2]*x)
return B[1] * 2.0 * (eBx - 1.0) * B[2] * eBx
model = odr.Model(func, fjacb=fjacb, fjacd=fjacd)
x = np.array([0., 0., 5., 7., 7.5, 10., 16., 26., 30., 34., 34.5, 100.])
y = np.array([1265., , , , , ,
, , , , , ])
ifixx = [, , , , , , , , , , , ]
data = odr.Data(x, y)
odr_obj = odr.ODR(data, model, beta0=[, -, -], ifixx=ifixx)
odr_obj.set_job(fit_type=)
odr_obj.set_iprint(init=, =, final=)
output = odr_obj.run()
Implicit Models
from scipy import odr
import numpy as np
def implicit_func(B, x):
"""Ellipse: B[2]*(x[0]-B[0])^2 + 2*B[3]*(x[0]-B[0])*(x[1]-B[1]) + B[4]*(x[1]-B[1])^2 - 1 = 0"""
return (B[2] * np.power(x[0] - B[0], 2) +
2.0 * B[3] * (x[0] - B[0]) * (x[1] - B[1]) +
B[4] * np.power(x[1] - B[1], 2) - 1.0)
model = odr.Model(implicit_func, implicit=1)
x_data = np.array([[0.5, 1.2, 1.6, 1.86, 2.12, 2.36, 2.44],
[-0.12, -0.6, -1.0, -1.4, -2.54, -3.36, -4.0]])
y_data = np.ones(7)
data = odr.Data(x_data, y_data)
odr_obj = odr.ODR(data, model, beta0=[1., 1., 1., 1., 1.])
output = odr_obj.run()
Linear Algebra
from scipy import linalg
import numpy as np
A = np.array([[1, 2], [3, 4]])
b = np.array([5, 6])
x = linalg.solve(A, b)
A_inv = linalg.inv(A)
det = linalg.det(A)
eigenvalues, eigenvectors = linalg.eig(A)
U, s, Vh = linalg.svd(A)
Q, R = linalg.qr(A)
L = linalg.cholesky(A @ A.T)
exp_A = linalg.expm(A)
sqrt_A = linalg.sqrtm(A)
Integration
from scipy import integrate
import numpy as np
def f(x):
return x**2
result, error = integrate.quad(f, 0, 1)
def f(y, x):
return x * y
result = integrate.dblquad(f, 0, 1, 0, 1)
x = np.linspace(0, 1, 100)
y = x**2
result = integrate.trapezoid(y, x)
result = integrate.simpson(y, x=x)
def deriv(y, t):
return -2 * y
y0 = 1
t = np.linspace(0, 5, 100)
solution = integrate.odeint(deriv, y0, t)
Interpolation
from scipy import interpolate
import numpy as np
x = np.array([0, 1, 2, 3, 4])
y = np.array([0, 2, 1, 3, 2])
f = interpolate.interp1d(x, y)
y_new = f(1.5)
f = interpolate.interp1d(x, y, kind='cubic')
x_new = np.linspace(0, 4, 100)
y_new = f(x_new)
x = y = np.arange(0, 5, 1)
z = np.random.rand(5, 5)
f = interpolate.interp2d(x, y, z, kind='cubic')
z_new = f(1.5, 2.5)
tck = interpolate.splrep(x, y, s=0)
y_new = interpolate.splev(x_new, tck)
tck, u = interpolate.splprep([x, y], s=0)
x_new, y_new = interpolate.splev(np.linspace(0, 1, 100), tck)
Signal Processing
from scipy import signal
import numpy as np
b, a = signal.butter(4, 0.1)
sos = signal.butter(4, 0.1, output='sos')
data = np.random.randn(1000)
filtered = signal.filtfilt(b, a, data)
x = np.array([1, 2, 3])
h = np.array([0, 1, 0.5])
y = signal.convolve(x, h)
corr = signal.correlate(x, h)
peaks, properties = signal.find_peaks(data, height=0.5, distance=10)
f, t, Sxx = signal.spectrogram(data, fs=1000)
window = signal.windows.hann(50)
Statistics
from scipy import stats
import numpy as np
norm = stats.norm(loc=0, scale=1)
pdf = norm.pdf(0)
cdf = norm.cdf(1.96)
quantile = norm.ppf(0.975)
samples = norm.rvs(size=1000)
data1 = np.random.randn(100)
data2 = np.random.randn(100) + 0.5
statistic, pvalue = stats.ttest_ind(data1, data2)
statistic, pvalue = stats.kstest(data1, 'norm')
observed = np.array([10, 20, 30])
expected = np.array([15, 15, 30])
statistic, pvalue = stats.chisquare(observed, expected)
corr, pvalue = stats.pearsonr(data1[:50], data2[:50])
mean = np.mean(data1)
std = np.std(data1)
desc = stats.describe(data1)
Image Processing
from scipy import ndimage
import numpy as np
image = np.random.rand(100, 100)
smoothed = ndimage.gaussian_filter(image, sigma=2)
edges = ndimage.sobel(image)
median = ndimage.median_filter(image, size=5)
binary = image > 0.5
dilated = ndimage.binary_dilation(binary)
eroded = ndimage.binary_erosion(binary)
rotated = ndimage.rotate(image, 45)
zoomed = ndimage.zoom(image, 2.0)
labeled, num_features = ndimage.label(binary)
sizes = ndimage.sum_labels(image, labeled, range(num_features + 1))
Spatial Algorithms
from scipy import spatial
import numpy as np
points1 = np.array([[0, 0], [1, 1]])
points2 = np.array([[2, 2], [3, 3]])
dist = spatial.distance.euclidean(points1[0], points2[0])
dist_matrix = spatial.distance.cdist(points1, points2)
points = np.random.rand(1000, 2)
tree = spatial.KDTree(points)
distances, indices = tree.query([0.5, 0.5], k=5)
hull = spatial.ConvexHull(points)
tri = spatial.Delaunay(points)
vor = spatial.Voronoi(points)
Constants
from scipy import constants
c = constants.c
h = constants.h
e = constants.e
G = constants.G
pi = constants.pi
golden = constants.golden
mile_in_meters = constants.mile
hour_in_seconds = constants.hour
eV_in_joules = constants.eV
kilo = constants.kilo
mega = constants.mega
Pitfalls
Sparse Array Indexing
from scipy import sparse
dia = sparse.dia_array([[1, 2], [3, 4]])
value = dia[0, 0]
csr = dia.tocsr()
value = csr[0, 0]
Duplicate Entries
from scipy import sparse
row = [0, 1, 1]
col = [0, 1, 1]
data = [1, 2, 3]
References