Scipy是Python中进行科学计算的一个第三方库,以Numpy为基础
一些SciPy的应用如下:
1.
特殊函数(scipy.special)
2.
积分(scipy.integrate)
3.
优化(scipy.optimize)
4.
插值
(scipy.interpolate)
5.
傅里叶变换(scipy.fftpack)
6.
信号处理(scipy.signal)
7.
线型代数(scipy.linalg)
8.
稀疏特征值问题(scipy.sparse)
9.
统计
(scipy.stats)
10.多维图像处理(scipy.ndimage)
子模块
描述
cluster
聚类算法
constants
物理数学常数
fftpack
快速傅里叶变换
integrate
积分和常微分方程求解
interpolate
插值
io
输入输出
linalg
线性代数
odr
正交距离回归
optimize
优化和求根
signal
信号处理
sparse
稀疏矩阵
spatial
空间数据结构和算法
special
特殊方程
stats
统计分布和函数
weave
C/C++ 积分
1.scipy.io文件的输入和输出
(1)导入相关依赖包
from scipy import io as spio
import numpy as np
(2)创建一个数组并保存到文件中
a = np.ones((3,3))
spio.savemat('file.mat',{'a':a})
data = spio.loadmat('file.mat',
struct_as_record=True)
data['a']
载入txt文件:numpy.loadtxt()/numpy.savetxt()
智能导入文本/csv文件:numpy.genfromtxt()/numpy.recfromcsv()
高速,有效率但numpy特有的二进制格式:numpy.save()/numpy.load()
2. 统计
2.1 分析随机数:
(1)生成服从指定分布的随机数
norm.rvs通过loc和scale参数可以指定随机变量的偏移和缩放参数,这里对应的是正态分布的期望和标准差。size得到随机数数组的形状参数。(也可以使用np.random.normal(loc=0.0, scale=1.0,
size=None))
import scipy.stats as stats
generated = stats.norm.rvs(size = 900)
Mean, std = stats.norm.fit(generated)
偏度(skewnes)描述的是概率分布的偏斜程度,我们需要做一个偏度检验。该检验有两个返回值,其中第二个返回值是p-value,即观察到的数据服从正态分布的概率,取值为0-1
stats.skewtest(generated)
峰度(kurtosis)描述的是概率分布的陡峭程度。该检验和偏度检验类似。
stats.kurtosistest(generated)
正态性检验(normality
test)可以检验数据服从正态分布的程度
stats.normaltest(generated)
使用Scipy我们很方便的得到数据所在区域中某一百分比处的数值
例如获取到95%处的值
stats.scoreatpercentile(generated, 95)
同样返过来也可以通过某一个数值获取其百分比
stats.percentileofscore(generated, 1)
(1)
求概率密度函数指定点的函数值
stats.norm.pdf正态分布概率密度函数
stats.norm.pdf(0,loc =
0,scale = 1)
(2)
求累计分布函数指定点的函数值
stats.norm.cdf正态分布累计概率密度函数
stats.norm.cdf(0,loc=3,scale=1)
(3)
累计分布函数的逆函数
stats.norm.ppf正态分布的累计分布函数的逆函数,即下分位点
z05 =stats.norm.ppf(0.05)
2.2 通用函数
名称
备注
rvs
产生服从指定分布的随机数
概率密度函数
cdf
累计分布函数
sf
残存函数(1-CDF)
ppf
分位点函数(CDF的逆)
isf
逆残存函数(sf的逆)
fit
对一组随机取样进行拟合,最大似然估计方法找出最适合取样数据的概率密度函数系数。
2.3常见分布
名称
含义
beta
beta分布
f
F分布
gamma
gam分布
poisson
泊松分布
hypergeom
超几何分布
lognorm
对数正态分布
binom
二项分布
uniform
均匀分布
chi2
卡方分布
cauchy
柯西分布
laplace
拉普拉斯分布
rayleigh
瑞利分布
t
学生T分布
norm
正态分布
expon
指数分布
2.4假设检验
(1)导入相关的函数:
·
正态分布:from scipy.stats import norm
·
独立双样本t检验,配对样本t检验,单样本t检验
from scipy.stats import ttest_ind, ttest_rel,
ttest_1samp
·
学生t分布:from scipy.stats import t
(2) 独立样本 t 检验
两组参数不同的正态分布:
n1 = norm(loc=0.3, scale=1.0)
n2 = norm(loc=0, scale=1.0)
从分布中产生两组随机样本:
n1_samples = n1.rvs(size=100)
n2_samples = n2.rvs(size=100)
将两组样本混合在一起:
samples = hstack((n1_samples,
n2_samples))
最大似然参数估计:
loc, scale = norm.fit(samples)
n = norm(loc=loc, scale=scale)
独立双样本t检验的目的在于判断两组样本之间是否有显著差异:
t_val, p = ttest_ind(n1_samples,
n2_samples)
p值小,说明这两个样本有显著性差异
(3) 配对样本 t 检验
配对样本指的是两组样本之间的元素一一对应,例如,假设我们有一组病人的数据:
pop_size = 35
pre_treat = norm(loc=0, scale=1)
n0 = pre_treat.rvs(size=pop_size)
经过某种治疗后,对这组病人得到一组新的数据:
effect = norm(loc=0.05, scale=0.2)
eff = effect.rvs(size=pop_size)
n1 = n0 + eff
新数据的最大似然估计:
loc, scale = norm.fit(n1)
post_treat = norm(loc=loc, scale=scale)
画图:
fig = figure(figsize=(10,4))
ax1 = fig.add_subplot(1,2,1)
h = ax1.hist([n0, n1], normed=True)
p = ax1.plot(x, pre_treat.pdf(x), 'b-')
p = ax1.plot(x, post_treat.pdf(x),
'g-')
ax2 = fig.add_subplot(1,2,2)
h = ax2.hist(eff, normed=True)
独立t检验:
t_val, p = ttest_ind(n0, n1)
高p值说明两组样本之间没有显著性差异。
配对t检验:
t_val, p = ttest_rel(n0, n1)
配对t检验的结果说明,配对样本之间存在显著性差异,说明治疗时有效的,符合我们的预期
3. 插值
插值是在直线或曲线上的两点之间找到值的过程
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
x = np.linspace(0, 4, 12)
y = np.cos(x**2/3+4)
print (x,y)
有两个数组。
假设这两个数组作为空间点的两个维度,使用下面的程序进行绘图,并看看它们的样子
plt.plot(x,y,'o')
plt.show()
(1) 一维插值
scipy.interpolate中的interp1d类是一种创建基于固定数据点的函数的便捷方法,可以使用线性插值在给定数据定义的域内的任意位置评估该函数。
from scipy import interpolate
from scipy.interpolate import interp1d
f1 = interp1d(x, y,kind = 'linear')
f2 = interp1d(x, y,kind = 'cubic')
创建更多长度的新输入以查看插值的明显区别。
对新数据使用旧数据的相同功能
xnew = np.linspace(0, 4,30)
plt.plot(x, y, 'o', xnew, f1(xnew), '-', xnew,
f2(xnew), '--')
plt.legend(['data', 'linear', 'cubic','nearest'],
loc = 'best')
plt.show()
(2)样条曲线
单变量样条
一维平滑样条拟合一组给定的数据点。
Scipy.interpolate中的UnivariateSpline类是创建基于固定数据点类的函数的便捷方法 –
scipy.interpolate.UnivariateSpline(x,y,w =
None,bbox =
[None,None],k =
3,s =
None,ext =
0,check_finite =
False)
下面来看看一个例子
import matplotlib.pyplot as plt
from scipy.interpolate import
UnivariateSpline
x = np.linspace(-3, 3, 50)
y = np.exp(-x**2) + 0.1 *
np.random.randn(50)
plt.plot(x, y, 'ro', ms = 5)
plt.show()
使用平滑参数的默认值
spl = UnivariateSpline(x, y)
xs = np.linspace(-3, 3, 1000)
plt.plot(xs, spl(xs), 'g', lw = 3)
plt.show()
手动更改平滑量
spl.set_smoothing_factor(0.5)
plt.plot(xs, spl(xs), 'b', lw = 3)
plt.show()
4. 拟合
曲线拟合
导入基础包:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
(1)多项式拟合
导入线多项式拟合工具
from numpy import polyfit, poly1d
产生数据:
x = np.linspace(-5, 5, 100)
y = 4 * x + 1.5
noise_y = y + np.random.randn(y.shape[-1]) *
2.5
画出数据:
%matplotlib inline
p = plt.plot(x, noise_y, 'rx')
p = plt.plot(x, y, 'b:')
进行线性拟合,polyfit是多项式拟合函数,线性拟合即一阶多项式:
一阶多项式 $y = a_1 x + a_0$ 拟合,返回两个系数
$[a_1, a_0]$。
画出拟合曲线:
p = plt.plot(x, noise_y, 'rx')
p = plt.plot(x, coeff[0] * x + coeff[1],
'k-')
p = plt.plot(x, y, 'b--')
还可以用poly1d生成一个以传入的coeff为参数的多项式函数:
f = poly1d(coeff)
p = plt.plot(x, noise_y, 'rx')
p = plt.plot(x, f(x))
(2)最小二乘拟合
导入相关的模块:
from scipy.linalg import lstsq
from scipy.stats import linregress
x = np.linspace(0,5,100)
y = 0.5 * x + np.random.randn(x.shape[-1]) *
0.35
plt.plot(x,y,'x')
要得到C,可以使用scipy.linalg.lstsq求最小二乘解。
这里,我们使用
1
阶多项式即N =
2,先将x扩展成X:
X = np.hstack((x[:,np.newaxis],
np.ones((x.shape[-1],1))))
C, resid, rank, s = lstsq(X, y)
C, resid, rank, s
画图:
p = plt.plot(x, y, 'rx')
p = plt.plot(x, C[0] * x + C[1], 'k--')
print "sum squared residual =
{:.3f}".format(resid)
print "rank of the X matrix =
{}".format(rank)
print "singular values of X =
{}".format(s)