对于理工科的学生,在写论文的时候经常数学建模,在模型验证的时候会花费大量的时间在基础的算法搭建和推演上,而SciPy是一个强大的开源python算法库和数学工具包,可以让我们脱离上述繁琐基础事务上。
SciPy (pronounced 'Sigh Pie') is an open-source software for mathematics, science, and engineering. It includes modules for statistics, optimization, integration, linear algebra, Fourier transforms, signal and image processing, ODE solvers, and more.
翻译过来就是,SciPy是一款用于数学、科学和工程领域的开源软件包,它包含统计、优化、积分、线性代数、傅里叶变换、信号和图像处理、ODE求解器等等。
另外,它是基于Numpy的科学算法库,使用NumPy数组作为基本的数据结构。
接下来,在使用过程中我们见识一下它的强大。
pycharm
可以使用以下命令进行安装:
pip install scipy
# or
python -m pip install scipy
输入以下命令,可以查看SciPy的版本和包含哪些模块:
import scipy
if __name__ == '__main__':
print('hello scipy')
print(scipy.__version__)
print(scipy.submodules)
输出:
hello scipy
1.10.1
['cluster', 'datasets', 'fft', 'fftpack', 'integrate', 'interpolate', 'io', 'linalg', 'misc', 'ndimage', 'odr', 'optimize', 'signal', 'sparse', 'spatial', 'special', 'stats']
可以看到SciPy 包含的模块有聚类、数据集、快速傅里叶变换、优化、线性代数、积分、插值、特殊函数、信号处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。
如果您需要的只是线性(又称折线)插值,则可以使用该numpy.interp例程。它需要两个数据数组x和来进行插值y,并使用第三个xnew点数组 来评估插值:
def test_interpolate():
x = np.linspace(0, 10, num=11)
y = np.cos(-x ** 2 / 9.2)
xnew = np.linspace(0, 10, num=1001)
ynew = np.interp(xnew, x, y)
plt.plot(xnew, ynew, '-', label='linear interp')
plt.plot(x, y, 'o', label='data')
plt.legend(loc='best')
plt.show()
示例画一个凸边型包含所有点:
def test_spatial():
rng = np.random.default_rng()
points = rng.random((30, 2)) # 30 random points in 2-D hull = ConvexHull(points)
plt.plot(points[:, 0], points[:, 1], 'o')
for simplex in hull.simplices:
plt.plot(points[simplex, 0], points[simplex, 1], 'k-')
plt.show()
scipy.special包含数学物理中众多特殊函数的定义。
可用的函数包括艾里函数、椭圆函数、贝塞尔函数、伽马函数、贝塔函数、超几何函数、抛物柱面函数、马蒂厄函数、球面波函数、struve 函数和开尔文函数。
还有一些低级统计函数不适合一般用途,因为模块提供了这些函数的更简单的接口stats。
大多数这些函数都可以采用数组参数并返回数组结果,遵循与 Numerical Python 中其他数学函数相同的广播规则。
其中许多函数还接受复数作为输入。
贝塞尔函数是具有实数或复数阶 alpha 的贝塞尔微分方程的一系列解:
def test_special():
theta = np.r_[0:2 * np.pi:50j]
radius = np.r_[0:1:50j]
x = np.array([r * np.cos(theta) for r in radius])
y = np.array([r * np.sin(theta) for r in radius])
z = np.array([drumhead_height(1, 1, r, theta, 0.5) for r in radius])
fig = plt.figure()
ax = fig.add_axes(rect=(0, 0.05, 0.95, 0.95), projection='3d')
ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap='RdBu_r', vmin=-0.5, vmax=0.5)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_xticks(np.arange(-1, 1.1, 0.5))
ax.set_yticks(np.arange(-1, 1.1, 0.5))
ax.set_zlabel('Z')
plt.title('Bessel functions')
plt.show()
傅立叶分析是一种将函数表示为周期性分量之和并从这些分量恢复信号的方法。当函数及其傅里叶变换都被离散化的对应物代替时,称为离散傅里叶变换(DFT)。DFT 已成为数值计算的支柱,部分原因在于一种非常快速的计算算法,称为快速傅立叶变换 (FFT),该算法为 Gauss (1805) 所熟知,并由 Cooley 和 Cooley 以其当前形式揭示出来。
示例使用 scipy.signal 中的 Blackman 窗并显示加窗的效果。
def test_fft():
# Number of sample points N = 600 # sample spacing T = 1.0 / 800.0 x = np.linspace(0.0, N * T, N, endpoint=False)
y = np.sin(50.0 * 2.0 * np.pi * x) 0.5 * np.sin(80.0 * 2.0 * np.pi * x)
yf = fft(y)
w = blackman(N)
ywf = fft(y * w)
xf = fftfreq(N, T)[:N // 2]
plt.semilogy(xf[1:N // 2], 2.0 / N * np.abs(yf[1:N // 2]), '-b')
plt.semilogy(xf[1:N // 2], 2.0 / N * np.abs(ywf[1:N // 2]), '-r')
plt.legend(['FFT', 'FFT w. window'])
plt.grid()
plt.show()
scipy.linalg包含numpy.linalg中的所有函数.
def test_linalg():
A = np.array([[1, 3, 5], [2, 5, 1], [2, 3, 8]])
B = linalg.inv(A)
C = linalg.inv(B) #double check 1 print(B)
print(C)
print(A.dot(linalg.inv(A))) #double check 2
[[-1.48 0.36 0.88]
[ 0.56 0.08 -0.36]
[ 0.16 -0.12 0.04]]
[[1. 3. 5.]
[2. 5. 1.]
[2. 3. 8.]]
[[ 1.00000000e 00 -1.11022302e-16 4.85722573e-17]
[ 3.05311332e-16 1.00000000e 00 7.63278329e-17]
[ 2.22044605e-16 -1.11022302e-16 1.00000000e 00]]