Python数据分析入门--SciPy库学习笔记

Posted szu_ljm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python数据分析入门--SciPy库学习笔记相关的知识,希望对你有一定的参考价值。

文章目录


前言

scipy是一个python开源的数学计算库,可以应用于数学、科学以及工程领域,它是基于numpy的科学计算库。主要包含了统计学、最优化、线性代数、积分、傅里叶变换、信号处理和图像处理以及常微分方程的求解以及其他科学工程中所用到的计算

scipy主要通过下面这些包来实现数学算法和科学计算:

子模块描述
cluster包含聚类算法,向量计算
constants物理和数学上的一些常数
fftpack快速傅里叶变换
integrate积分和常微分方程的求解
interpolate插值和平滑的样条函数
io输入和输出
linalg线性代数
ndimageN维的图像处理
odr回归正交距离
optimize优化和寻根方程
signal信号处理
spatial空间数据结构和算法
sparse稀疏矩阵
special特殊的函数
stats统计分布和函数

Scipy库简单入门

1.cluster模块

聚类分析是在数据中发现数据对象之间的关系,将数据进行分组,组内的相似性越大,组间的差别越大,则聚类效果越好。聚类分析常用的距离度量有欧式距离、曼哈顿距离、切比雪夫距离和明可夫斯基距离等。

K均值聚类是一种在一组未标记数据中查找聚类和聚类中心的方法。 直觉上,我们可以将一个群集(簇聚)看作一组数据点,其点间距离与群集外点的距离相比较小。 给定一个K中心的初始集合,K均值算法将重复以下步骤

  1. 选择 K 个初始质心(K需要用户指定),初始质心随机选择即可,每一个质心为一个类
  1. 对剩余的每个样本点,计算它们到各个质心的欧式距离,并将其归入到相互间距离最小的质心所在的簇,计算各个新簇的质心。
  1. 在所有样本点都划分完毕后,根据划分情况重新计算各个簇的质心所在位置,然后迭代计算各个样本点到各簇质心的距离,对所有样本点重新进行划分
  1. 重复2. 和 3.,直到质心不在发生变化时或者到达最大迭代次数时
from scipy.cluster.vq import kmeans,vq,whiten
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(30,30))
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
data1 = np.random.rand(10,3) + np.array([.5,.5,.5])
data2 = np.random.rand(10,3)
data = np.vstack((data1,data2))
data = whiten(data)
centre,_ = kmeans(data,3)
cluster,_ = vq(data,centre)
ax1.scatter(data1,data2)

a = []  # 下面都是数据可视化操作
b = []
c = []
for i in range(len(cluster)):
    if cluster[i] == 0:
        a.append(data[i])
    elif cluster[i] == 1:
        b.append(data[i])
    else:
        c.append(data[i])

xx = []
for i in range(3):
    xx.append([])
# 样本数据纵坐标列表
yy = []
for i in range(3):
    yy.append([])
m = []
m = [a, b, c]

for i in range(3):
    for j in range(len(m[i])):
        xx[i].append(m[i][j][0])
    for j in range(len(m[i])):
        yy[i].append(m[i][j][1])
    ax2.scatter(xx[i], yy[i], label=i)
    plt.legend()
plt.show()

print(data)
print('\\n')
print(centre)
print('\\n')
print(cluster)


#/usr/bin/python3.8 /home/ljm/PycharmProject/pythoncode1/code8.py 
[[1.14865697 2.69405034 1.73788065]
 [3.23341434 3.23294749 3.53956713]
 [3.2839023  3.59125444 3.9455198 ]
 [2.51874233 2.77678538 1.57993031]
 [2.17842407 1.75756848 3.80120161]
 [2.10036682 2.59059014 1.83130737]
 [2.78107445 2.77670545 3.22940596]
 [2.18464206 2.80216035 2.46133769]
 [2.0737308  2.41947047 1.83787354]
 [2.95571045 4.05702503 3.41077657]
 [1.50081545 1.93798131 1.78342349]
 [0.77652033 2.22745268 1.39755954]
 [0.05806498 1.22388636 0.87025516]
 [0.71156678 2.42998927 2.58839209]
 [0.36591912 0.31864204 2.4776798 ]
 [0.30741828 0.67968106 1.47645486]
 [0.46902599 0.56745425 0.17545723]
 [1.25626675 1.47109371 1.57507801]
 [0.93078627 2.6552914  1.28276725]
 [2.05924502 0.9403261  2.88461438]]


[[0.30010709 0.69741593 1.24996176]
 [1.56921269 2.26774465 1.90546948]
 [2.88650512 3.08310018 3.58529421]]


[1 2 2 1 2 1 2 1 1 2 1 1 0 1 0 0 0 1 1 1]

#Process finished with exit code 0

k-means算法的实例说明

假定某共用办公室有两个人使用,他们使用办公室的时候都会用空调遥控器设置房间的温度。但空调遥控器显示面板坏掉了,只能通过加减温度的方式盲调整。但已知他们习惯的温度不同。办公室的温度计有记录功能,每天记录12 小时的温度,每15 分钟记录一次,根据一个月所记录的数据,通过聚类算法,算出这两个人的喜好温度,并估算他们各使用办公室多少时间。可以认为这两个人使用办公室的时候室内温度是不同方差和不同均值的正态分布随机数,生成模拟数据,并用matplotlib 画出数据的直方图。使用K 均值聚类算法将模拟数据分成两个簇,两个簇的最佳温度为两人需要的空调温度,通过预判每个人使用办公室的时间来实现空调调温自动化。

2. constants模块

Scipy的constants模块是一个包含大量的数学和物理常量的库,可用于一般科学领域

import scipy.constants
print(scipy.constants.pi)
print('\\n')
print(scipy.constants.speed_of_light)
print('\\n')
print(scipy.constants.Planck)

#/usr/bin/python3.8 /home/ljm/PycharmProject/pythoncode1/code4.py 
3.141592653589793


299792458.0


6.62607015e-34

#Process finished with exit code 0

下面是一些常见的数学和物理常量汇总

数学常量描述
pi圆周率
golden黄金比例
物理常量描述
speed_of_light真空中的光速
mu_0磁常数
epsilon_0真空介电常数
Planck普朗克常数
G万有引力常数
g标准重力加速度
e基本电荷
gas_constant摩尔气体常数
fine_structure精细结构常数
N_A阿伏伽德罗常数
Boltzmann玻尔兹曼常数
Stefan_Boltzmann斯蒂芬-玻尔兹曼常数
m_e电子质量
m_p质子质量
m_n中子质量

3. fftpack模块

在数学中,傅里叶级数(Fourier series)是把类似波的函数表示成简单正弦波的方式。更正式地说法是,它能将任何周期性函数或周期信号分解成一个(可能由无穷个元素组成的)简单振荡函数的集合,即正弦函数和余弦函数。

傅里叶变换是一种数学变换,它将一个函数(通常是一个时间的函数,或一个信号)分解成它的组成频率,例如用组成音符的音量和频率表示一个音乐和弦。其本质是一种线性积分变换,用于信号在时域(或空域)和频域之间的变换,在物理学和工程学中有许多应用。实际上傅里叶变换就像化学分析,确定物质的基本成分;信号来自自然界,也可对其进行分析,确定其基本频率成分。

快速傅立叶变换(FFT)是一种计算数字信号序列的离散傅立叶变换(DFT)或其逆变换(IDFT)的算法。傅里叶分析将信号从其原始域(通常是时间或空间)转换为频域的表示,反之亦然。DFT是通过将一系列值分解成不同频率的分量来获得的。这个操作在很多领域中都很有用,但是直接从定义中计算它通常太慢而不实际。FFT通过将DFT矩阵分解成稀疏(大部分为零)因子的乘积来快速计算这种转换。所以其本质是实现离散傅立叶变换的一种优化算法,将时间复杂度从O(N^2)降低为O(NlogN),其中N为待计算序列的长度。当N非常大时,这中优化在时间维度上提升是非常显著的。

傅里叶变换广泛应用于信号和噪声处理,图像处理,音频信号处理等领域,比如51单片机会利用快速傅里叶变换来实现滤波。SciPy提供fftpack模块,可让用户计算快速傅立叶变换。

import numpy as np
from scipy import fftpack
time_step = 1
period = 5.
time_vec = np.arange(0, 20, time_step)
sig = np.sin(2 * np.pi / period * time_vec) + 0.5 *np.random.randn(time_vec.size)
print(sig.size)
print('\\n')
print(sig)
print('\\n')

sample_freq = fftpack.fftfreq(sig.size, d = time_step)
sig_fft = fftpack.fft(sig)
print(sig_fft)

#/usr/bin/python3.8 /home/ljm/PycharmProject/pythoncode1/code4.py 
20


[ 0.8619723   0.80046426  1.47924167 -0.75314181 -1.25099334  0.51117803
  1.74449108  2.02777642 -0.82128671 -0.45706612 -0.5045473   0.30284392
  0.30628348 -1.33838885 -0.7817602   0.16376441  0.84729352 -0.1188564
 -0.45284573 -0.82521711]


[ 1.74120551 -0.j          1.39666054 -3.7049906j
 -0.7001181  +2.21076727j  3.55673302 -1.71079756j
  0.88382092-10.81685692j -1.54131028 +1.5186949j
 -0.65092151 +1.57638056j  0.43460041 -0.68361725j
  0.82649494 +2.59411121j  2.98591428 -1.9451872j
  1.11449199 -0.j          2.98591428 +1.9451872j
  0.82649494 -2.59411121j  0.43460041 +0.68361725j
 -0.65092151 -1.57638056j -1.54131028 -1.5186949j
  0.88382092+10.81685692j  3.55673302 +1.71079756j
 -0.7001181  -2.21076727j  1.39666054 +3.7049906j ]

#Process finished with exit code 0

我们通过上述程序利用非正弦波模拟一个嘈杂的输入信号,fftfreq函数将生成采样频率,然后利用fft函数计算快速傅里叶变换。

4. integrate 模块

高等数学里的大量的积分都是可以被分析积分的,但生活中有很多积分是我们不可积的。当一个函数不能被分析积分,或者很难分析积分时,通常会转向数值积分方法。 SciPy有许多用于执行数值积分的程序。 它们中的大多数都在同一个scipy.integrate库中

import scipy.integrate
import numpy as np
g = lambda x:np.cosh(x)
f = lambda x:np.exp(-x**2)
a = scipy.integrate.quad(f, 0, 2)
b = scipy.integrate.quad(g, 0, 2)
print(a)
print('\\n')
print(b)

#/usr/bin/python3.8 /home/ljm/PycharmProject/pythoncode1/code6.py 
(0.8820813907624215, 9.793070696178202e-15)


(3.6268604078470186, 4.0266239318931457e-14)

#Process finished with exit code 0

积分函数会返回两个值,其中第一个数字是积分值,第二个数值是积分值绝对误差的估计值。后面我们还会接触到多重积分,二重积分可以理解为求一个的物体体积(高对底面积的积分),三重积分可以理解为求一个密度分布不均匀物体的质量(密度函数对体积的积分),二重和三重积分的机制已被包含到函数dblquad,tplquad和nquad中。,这些函数分别需要四个或六个参数。

import scipy.integrate
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.ticker as ticker
from matplotlib.ticker import MultipleLocator

fig = plt.figure(figsize=(30,30))
ax = Axes3D(fig)
g = lambda x, y: x**2 + y**2
f = lambda x: 0
l = lambda y: 0
x = np.arange(1, 2, 0.05)
y = np.arange(1, 2, 0.05),
x, y = np.meshgrid(x, y)
z = x**2 + y**2
a = scipy.integrate.dblquad(g, 1, 2, 1, 2)
ax.plot_surface(x, y, z, rstride=1, cstride=1, cmap='rainbow')
plt.show()
print(a)

#/usr/bin/python3.8 /home/ljm/PycharmProject/pythoncode1/code6.py 
(4.666666666666666, 7.021774688857003e-14)

#Process finished with exit code 0

dblquad函数的一般形式包含五个参数(func,a,b,gfun,hfun)。 其中,func是要积分函数的名称,'a’和’b’分别是x变量的下限和上限,而gfun和hfun是定义变量y的下限和上限的函数名称。以下是常用函数

函数名称描述
quad一重积分
dblquad二重积分
tplquad三重积分
nquadn重积分
fixed_quad高斯积分,阶数n
quadrature高斯正交到容差
rombergRomberg积分
trapz梯形规则
cumtrapz梯形法则累计计算积分
simps辛普森规则
polyint分析多项式积分
poly1d辅助函数polyint

5. interpolate 模块

插值是在直线或曲线上的两点之间找到值的过程,比如在给出有限的离散数据点时,当我们想要根据数据点拟合出一条曲线,就可以利用插值的方法。 这种插值工具不仅适用于统计学,而且在科学,商业或需要预测两个现有数据点内的值时也很有用。

import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(30,30))
x1 = np.linspace(-2, 2, 20)
x2 = np.linspace(-2, 2, 100)
y = np.cosh(x1**2)
f1 = interpolate.interp1d(x1, y,kind = 'linear')
f2 = interpolate.interp1d(x1, y, kind = 'cubic')
plt.plot(x1,y,'o',x2,f1(x2),x2,f2(x2))
plt.show()

interp1d是一种创建基于固定数据点的函数的便捷方法,可以使用线性插值在给定数据定义的域内的任意位置评估该函数,拟合精度随着插值的数量增大而提高,这些函数对于给定的输入x返回y, 第三个参数表示插值的类型。

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline
fig = plt.figure(figsize=(30,30))
x1 = np.linspace(-5, 5, 50)
x2 = np.linspace(-5, 5, 500)
y = np.sinh(x1**2) - np.random.randn(50)
spl = UnivariateSpline(x1, y)
spl.set_smoothing_factor(0.5)
plt.plot(x1, y, 'bo', ms = 5)
plt.plot(x2, spl(x2), 'y', lw = 3)
plt.show()

我们也可以画出平滑的一维曲线来拟合一组给定的数据点,interpolate模块中的UnivariateSpline类是创建基于固定数据点类的函数的便捷方法,该方法可以直接调节曲线的平滑度。

6. linalg模块

Scipy库具有很强很快的线性代数求解能力,所有这些线性代数例程都需要一个可以转换为二维数组的对象,这些例程的输出也是一个二维数组。linalg模块下的solve方法可以求解线性方程,返回的结果是变量的解的数组

from scipy import linalg
import numpy as np

# 2x+ 2y= 2
# x- y= 4
# 5y+ 5z= -1

arr1 = np.array([[2, 2, 0], [1, -1, 0], [0, 5, 5]]) 
arr2 = np.array([2, 4, -1])
arr3 = linalg.solve(arr1, arr2)
print (arr3)

#/usr/bin/python3.8 /home/ljm/PycharmProject/pythoncode1/code9.py 
[ 2.5 -1.5  1.3]

#Process finished with exit code 0

行列式是线性代数中经常使用的, 在SciPy的linalg模块中,我们可以通过det方法计算行列式并返回一个标量值。

from scipy import linalg
import numpy as np
arr1 = np.array([[2, 2, 0], [1, -1, 0], [0, 5, 5]])
arr2 = np.arange(1,5).reshape(2,2)
l,v = linalg.eig(arr2)
print(linalg.det(arr1))
print('\\n')
print(l)
print('\\n')
print(v)

#/usr/bin/python3.8 /home/ljm/PycharmProject/pythoncode1/code9.py 
-20.0


[-0.37228132+0.j  5.37228132+0.j]


[[-0.82456484 -0.41597356]
 [ 0.56576746 -0.90937671]]

#Process finished with exit code 0

特征值和特征向量问题是最常用的线性代数运算之一,A为n阶矩阵,若数λ和n维非0列向量x满足Ax=λx,那么数λ称为A的特征值,x称为A的对应于特征值λ的特征向量, 我们可以通过linalg模块里的eig方法来计算方阵(A)的特征值(λ)和相应的特征向量(x) 。

7. ndimage模块

边缘检测是一种用于查找图像内物体边界的图像处理技术。它通过检测亮度不连续性来感知边缘,边缘检测常用于图像处理,计算机视觉和机器视觉等领域的图像分割和数据提取。

from scipy import ndimage
import numpy as np
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(30,30))
im1 = np.zeros((256, 256))
im1[64:-64, 64:-64] = 1
im1[90:-90,90:-90] = 2
im1 = ndimage.gaussian_filter(im1, 6)

sx = ndimage.sobel(im1, axis = 0, mode = 'constant')
sy = ndimage.sobel(im1, axis = 1, mode = 'constant')
im2 = np.hypot(sx, sy)
plt.imshow(im1)
plt.show()
plt.imshow(im2)
plt.show()

我们刚开始生成256*256像素点的图像,并用ndimage模块下的gaussian_filter方法来调整图像模糊度,接着使用ndimage提供的Sobel函数检测这些彩色块的边缘,NumPy提供了Hypot函数来将两个合成矩阵合并为一个。

8. optimize模块

optimize模块包含很多优化算法(这里主要介绍最小二乘和求根):

各种算法的无约束和约束最小化多元标量函数(minimize())

全局优化程序(anneal(),basinhopping())

最小二乘最小化(leastsq()) 和曲线拟合(curve_fit())

以上是关于Python数据分析入门--SciPy库学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

NumPy快速入门笔记

『Python』Numpy学习指南第十章_高端科学计算库scipy入门(系列完结)

Python机器学习入门之导学+无监督学习

python scipy库

[学习笔记] [数据分析] 01.Python入门

Python数模笔记-Scipy库线性规划问题