6 NumPy的数学和统计函数

NumPy提供了很多的数学和统计学相关的函数,本章就NumPy的数学函数和统计学函数的详细使用进行展示和讲解。

本章使用的数据来自于鸾尾花数据iris.data 下载后请保存成iris.csv文件。

6.1 numpy下的文件读写

NumPy提供了两个函数可以将数据保存到文件savetxt和从文件读取数据到数组loadtxt。

loadtxt读取文件内容

鸾尾花数据的每行有5个字段,前四个字段是实数,最后一个字段是字符串,所以通过numpy的loadtxt读[鸾尾花数据时需要两次读取回来,第一次读取四个实数数据,第二次读取回来该数据的分类即名字class。

from numpy import *
a = loadtxt("iris.data", dtype = float64, delimiter=',', usecols = [0, 1, 2, 3])
print a
b = loadtxt("iris.data", dtype = "S", delimiter=',', usecols = [4])
print b
for x in range(len(b)):
    print a[x], "is ", b[0]

loadtxt函数的参数比较多,dtype指定的是读取数据类型,默认是float型的数据,delimiter指定如何分割每行的数据得到字段数据,而usecols的作用是每行的数据取回那些字段的值,从0开始。有些csv数据文件第一行不是数据而是数据的字段名字可以使用skiprows 形参指定不读取第0行或者头几行。comment形参的作用是某行以井号#开始这行数据跳过不读取视为注释。

由于鸾尾花数据的每行是数值和字符串混合的,所以dtype可以自定义一个复杂的数据类型t = t = dtype([('sepal_length', 'f'),('sepal_width','f'),('petal_length','f'),('petal_width','f'),('class','S20')])然后一次性读取所有的数据。

from numpy import *
t = dtype([('sepal_length', 'f'),('sepal_width','f'),('petal_length','f'),('petal_width','f'),('class','S20')])
a = loadtxt("iris.data", dtype = t, delimiter=',')
print a

savetxt存储数据到文件

还是以鸾尾花数据为例展示一下数据存储。

from numpy import *
t = dtype([('sepal_length', 'f'),('sepal_width','f'),('petal_length','f'),('petal_width','f'),('class','S20')])
a = loadtxt("iris.data", dtype = t, delimiter=',')
print a
r = savetxt("iris.csv", a, fmt='%3.1f:%3.1f:%3.1f:%3.1f:%s')

6.2 NumPy的数学与统计函数

6.2.1 纯数学函数

NumPy里提供了很多的数学相关的函数,如下表所示:

函数 说明
np.abs() np.fabs() 计算数组各元素的绝对值
np.sqrt() 计算数组各元素的平方根
np.square() 计算数组各元素的平方
np.log(x),np.log10(x),np.log2(x) 计算数组各元素的自然对数、10底对数和2底对数
np.ceil(x),np.floor(x) 计算数组各元素的ceiling值或floor值
np.rint(x) 计算数组各元素的四舍五入值
np.modf(x) 将数据各元素的整数和小数部分以两个独立的数组形式返回
np.cos/cosh/sin/sinh/tan/tanh 计算数据各元素的普通型和双典型的三角函数
np.exp(x) 计算数组各元素的指数值

这些函数可以根据需求自行选择使用,下面给出一个例子,先提取鸾尾花数据前2列的数据到a和b数组,然后以a数组测试使用一些数学函数。

from numpy import *
import numpy as np
a, b = loadtxt("iris.data",  delimiter=',', usecols = [0, 1],unpack=True)
print a
print b
print np.sqrt(a)

6.2.2 随机数函数

在numpy下的random模块里有很多可以产生随机数构成数组的函数,如下表所示:

函数 说明
rand(d0,d1,...,dn) 根据d0-dn创建随机数数组,浮点数,[0,1),均匀分布
randn(d0,d1,...,dn) 根据d0-dn创建随机数数组,标准正态分布
randint(low[,high,shape]) 根据shape创建随机整数或整数数组,范围是[low,high)
seed(s) 随机数种子,s是给定的种子值
shuffle(a) 根据数组a的第1轴进行随排列,改变数组a
permutation(a) 根据数组a的第1轴产生一个新的乱序数组,不改变数组a
choice(a[,size,replace,p]) 从一维数组a中以概率p抽取元素,形成size形状新数组replace表示是否可能重用元素,默认为False
uniform(low,high,size) 产生具有均匀分布的数组,low起始值,high结束值,size为形状
normal(loc,scale,size) 产生具有正态分布的数组,loc为均值,scale标准差,size为形状
poisson(lam,size) 产生具有泊松分布的数组,lam为随机事件发生率,size为形状

下面试试normal函数,大数据相关的教程里常使用normal等函数产生一些随机样本或者测试集,故经常会看到normal、uniform等函数。

#coding:utf-8
import numpy as np
# 产生20个均值为2、标准差为0.1满足正态分布的随机数序列
a = np.random.normal(2, 0.1, 20)
print a

程序执行结果:

[ 1.99464964  2.01571241  1.8533784   2.01801614  2.00696632  2.10531441
  1.94375317  2.13434834  1.94393169  2.15816452  1.91364328  2.13395142
  1.99393622  2.12242607  2.01800799  2.16292735  2.00445096  2.14917052
  1.93596385  1.92199622]

另外shuffle比较有用,可以打乱数组里各元素位置顺序。

import numpy as np
a = np.random.normal(2, 0.1, 20)
print a
np.random.shuffle(a)
print a

程序执行结果:

[ 2.07455638  2.01737716  .. 1.86696906]
[ 2.04238934  1.92716726  .. 2.10456049]

6.2.3 numpy的统计函数

NumPy 有很多有用的统计函数,可以很方便地从数组中给定的元素中查找最小,最大,百分标准差和方差等。

函数 说明
sum(a,axis=None) 根据给定axis计算数组a相关元素之和,axis整数或元组
mean(a,axis=None) 根据给定axis计算数组a相关元素的期望,axis整数或元组
average(a,axis=None,weights=None) 根据给定axis计算数组a相关元素的加权平均值
std(a,axis=None) 根据给定轴axis计算数组a相关元素的标准差
var(a,axis = None) 根据给定轴axis计算数组a相关元素的方差
cov(a,axis = None) 计算协方差
corrcoef 计算相关系数,参阅
min(a) max(a) 计算数组a中元素的最小值,最大值
argmin(a) argmax(a) 计算数组a中元素的最小值,最大值的降一维后下标
unravel_index(index,shape) 根据shape将一维下标index转换成多维下标
ptp(a) 计算数组a中元素最大值和最小值的差
median(a) 计算数组a中元素的中位数(中值)

下面还是使用鸾尾花数据iris.data 的头两列数据来测试使用一下这些函数。

from numpy import *
import numpy as np
a, b = loadtxt("iris.data",  delimiter=',', usecols = [0, 1],unpack=True)
print a
print b
print column_stack([a, b])
print average(a)
print mean(a)
print np.max(a)
print argmax(a)
print np.min(a)
print argmin(a), a[np.argmin(a)]
print ptp(a)
print std(a)
print median(a)
print sqrt(a), square(a)
print rint(a)
print ceil(a)

6.2.4 numpy的梯度函数

函数 说明
np.gradient(f) 计算数组中元素的梯度,当f为多维时,返回每个维度梯度。

梯度函数是深度学习里bp核心。

6.2.5 线性代数相关函数

numpy.linalg模块包含线性代数的函数。使用这个模块,可以计算逆矩阵、求特征值、解线性方程组以及求解行列式等。

函数 说明
det(ndarray) 计算矩阵列式
eig(ndarray) 计算方阵的特征值和特征向量
inv(ndarray) pinv(ndarray) 计算方阵的逆计算方阵的Moore-Penrose伪逆
qr(ndarray) 计算qr分解
svd(ndarray) 计算奇异值分解svd
solve(ndarray) 解线性方程组Ax = b,其中A为方阵
lstsq(ndarray) 计算Ax=b的最小二乘解

下面举几个例子:

例子1:qr分解

QR分解法是三种将矩阵分解的方式之一。这种方式,把矩阵分解成一个正交矩阵与一个上三角矩阵的积。QR 分解经常用来解线性最小二乘法问题。

import numpy as np
from numpy.linalg import qr
aa = np.array([[0,3,1],[0,4,-2],[2,1,2]])
qq, rr = qr(aa)
print "qq", "*" * 18
print qq
print "rr", "*" * 18
print rr
print "aa", "*" * 18
print aa
print "qq.rr", "*" * 15
print qq.dot(rr)

程序执行结果:

qq ******************
[[ 0.  -0.6 -0.8]
 [-0.  -0.8  0.6]
 [-1.   0.   0. ]]
rr ******************
[[-2. -1. -2.]
 [ 0. -5.  1.]
 [ 0.  0. -2.]]
aa ******************
[[ 0  3  1]
 [ 0  4 -2]
 [ 2  1  2]]
qq.rr ***************
[[ 0.  3.  1.]
 [ 0.  4. -2.]
 [ 2.  1.  2.]]

例子2:inv求逆矩阵

from numpy.linalg import inv
xx = np.array([[-2,1],[4,-3]])
yy = inv(xx)
print xx
print yy
print xx.dot(yy)

程序执行结果:

[[-2  1]
 [ 4 -3]]
[[-1.5 -0.5]
 [-2.  -1. ]]
[[ 1.  0.]
 [ 0.  1.]]