8 Numpy
Numpy(全名为Numerical Python)是Python数值计算最重要的基础包。大部分计算都是以Numpy的数据结构为基础的。
Numpy本身并没有很多高级的数据分析功能和算法,但理解Numpy的数组机器计算可以帮助我们使用其他的包。接下来,我将着重于介绍Nunmpy包比较常用的一些功能。
因为Anaconda自带Numpy包,所以我们可以直接使用Numpy包。在使用包之前,需要进行调用:
In [1]: import numpy as np
8.1 ndarray
这是Numpy包最常用的一个数据结构。你可以利用它来储存数据并执行一些数学计算,计算语法与数学运算符号很像。下面介绍关于ndarray的一些基础语法。
- 创建ndarray
我们使用array
函数创造ndarray。它可以接受基本的数据类型,并产生对应的ndarray数组。
In [2]: data1 = (1,2,3)
In [3]: arr1 = np.array(data1)
In [4]: arr1
Out[4]: array([1, 2, 3])
同时,多重的数据(比如列表里面还含有元组)会被转化成多维array:
In [5]: data2 = [(1,2,3),(4,5,6)]
In [6]: arr2 = np.array(data2)
In [7]: arr2
Out[7]:
array([[1, 2, 3],
[4, 5, 6]])
还有一些常用的新建array的方法。
zeros
和ones
函数分别可以创建指定长度或形状的array。函数里面只需要写一个表示形状的元组即可。
In [8]: np.zeros(5)
Out[8]: array([0., 0., 0., 0., 0.])
In [9]: np.zeros((2,3))
Out[9]:
array([[0., 0., 0.],
[0., 0., 0.]])
In [10]: np.ones((2,3))
Out[10]:
array([[1., 1., 1.],
[1., 1., 1.]])
arange
函数的功能和range
函数功能是一样的:
In [11]: np.arange(5)
Out[11]: array([0, 1, 2, 3, 4])
eye
函数可以生成的单位矩阵:
In [12]: np.eye(5)
Out[12]:
array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
- ndarray的运算
通过array运算,可以对数据进行批量运算,提高效率。
In [13]: a = np.ones((2,2))
In [14]: b = np.eye(2)
数组之间的加法:
In [15]: a + b
Out[15]:
array([[2., 1.],
[1., 2.]])
减法:
In [16]: a - b
Out[16]:
array([[0., 1.],
[1., 0.]])
array对应元素相乘(Hadamard乘法):
In [17]: a * b
Out[17]:
array([[1., 0.],
[0., 1.]])
数字与array相乘:
In [18]: 3 * a
Out[18]:
array([[3., 3.],
[3., 3.]])
数字与array相除:
In [19]: a / 3
Out[19]:
array([[0.33333333, 0.33333333],
[0.33333333, 0.33333333]])
array对应元素相除:
In [20]: b /(3*a)
Out[20]:
array([[0.33333333, 0. ],
[0. , 0.33333333]])
矩阵乘法:
In [21]: a.dot(b)
Out[21]:
array([[1., 1.],
[1., 1.]])
可以看到,array运算符号和数学运算其实差不多的。
8.2 矩阵
矩阵在数值计算中起到了很重要的作用,在多元统计中,更是涉及到了很多矩阵运算。numpy包也有对应操作方式。
生成矩阵:
In [22]: c = np.mat(np.array([[1,2,3],[4,5,6],[7,8,9]]))
In [23]: c
Out[23]:
matrix([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
矩阵的加法,减法,乘法,对应元素相乘(Hadamard乘法):
In [24]: d = np.mat(np.ones([3,3]))
In [25]: d
Out[25]:
matrix([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
In [26]: c + d
Out[26]:
matrix([[ 2., 3., 4.],
[ 5., 6., 7.],
[ 8., 9., 10.]])
In [27]: c - d
Out[27]:
matrix([[0., 1., 2.],
[3., 4., 5.],
[6., 7., 8.]])
In [28]: c*d
Out[28]:
matrix([[ 6., 6., 6.],
[15., 15., 15.],
[24., 24., 24.]])
In [29]: np.multiply(c,d)
Out[29]:
matrix([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]])
矩阵转置:
In [30]: e = np.mat([[1,2,3],[4,5,6]])
In [31]: e
Out[31]:
matrix([[1, 2, 3],
[4, 5, 6]])
In [32]: e.transpose()
Out[32]:
matrix([[1, 4],
[2, 5],
[3, 6]])
矩阵求逆:
In [33]: e.I
Out[33]:
matrix([[-0.94444444, 0.44444444],
[-0.11111111, 0.11111111],
[ 0.72222222, -0.22222222]])
提取矩阵对角线元素:
In [34]: np.diag(e)
Out[34]: array([1, 5])
In [35]: np.diag(np.diag(e))
Out[35]:
array([[1, 0],
[0, 5]])
计算矩阵的迹:
In [36]: np.trace(c)
Out[36]: 15
8.3 基本统计方法
numpy包可以计算数据的基本统计量,比如均值、标准差等等。
计算数据的和:
In [34]: e.sum()
Out[34]: 21
计算数据的均值:
In [35]: e.mean()
Out[35]: 3.5
计算数据的标准差:
In [36]: e.std()
Out[36]: 1.707825127659933
计算数据的方差:
In [37]: e.var()
Out[37]: 2.9166666666666665
计算数据的最小值:
In [38]: e.min()
Out[38]: 1
计算数据的最大值:
In [39]: e.max()
Out[39]: 6
计算数据最小值所在的位置(索引):
In [40]: e.argmin()
Out[40]: 0
计算数据最大值所在的位置(索引):
In [41]: e.argmax()
Out[41]: 5
需要注意的是,如果在括号里面加0
,那么就是计算每列对应的统计量;在括号里面加入1
,计算的就是每行对应的统计量。下面以mean
函数为例:
In [42]: e.mean(0)
Out[42]: matrix([[2.5, 3.5, 4.5]])
In [43]: e.mean(1)
Out[43]:
matrix([[2.],
[5.]])
8.4 例子
为了测量某种橡胶的性能,随机抽取5个样品,测量其三项指标:硬度,变形和弹性,数据如下:
No. | 硬度 | 变形 | 弹性 |
---|---|---|---|
1 | 65 | 45 | 27.6 |
2 | 70 | 45 | 30.7 |
3 | 70 | 48 | 31.8 |
4 | 69 | 46 | 32.6 |
5 | 66 | 50 | 30.1 |
下面利用Numpy,这个数据进行简单的统计分析:生成样本数据矩阵:
In [44]: X = np.mat([[ 65,45,27.6],[70,45,30.7],[ 70,48,31.8],[69,46,32.6],[66,50,30.1]])
In [45]: X
Out[45]:
matrix([[65. , 45. , 27.6],
[70. , 45. , 30.7],
[70. , 48. , 31.8],
[69. , 46. , 32.6],
[66. , 50. , 30.1]])
计算每个变量的均值,方差,最大值,最小值:
In [46]: X.mean(0)
Out[46]: matrix([[68. , 46.8 , 30.56]])
In [47]: X.var(0)
Out[47]: matrix([[4.4 , 3.76 , 2.9384]])
In [48]: X.max(0)
Out[48]: matrix([[70. , 50. , 32.6]])
In [49]: X.min(0)
Out[49]: matrix([[65. , 45. , 27.6]])
计算样本离差阵。样本离差阵有如下的表达式,本例子中:
In [50]: I5 = np.mat(np.eye(5))
In [51]: I5
Out[51]:
matrix([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
In [52]: V = X.transpose()*(I5 - 0.2*np.mat(np.ones([5,5])))*X
In [53]: V
Out[53]:
matrix([[22. , -3. , 14.6 ],
[-3. , 18.8 , 3.46 ],
[14.6 , 3.46 , 14.692]])
计算样本协方差阵:
In [54]: S = V/4
In [55]: S
Out[55]:
matrix([[ 5.5 , -0.75 , 3.65 ],
[-0.75 , 4.7 , 0.865],
[ 3.65 , 0.865, 3.673]])
8.5 生成随机数
Numpy中可以生成各种分布的随机数,下面是一些常用的功能:
rand(size)
:产生个数为n的0到1均匀分布随机数
In [56]: np.random.rand(10)
Out[56]:
array([0.23165881, 0.8150714 , 0.04643356, 0.27011201, 0.25915723,
0.28692941, 0.59688985, 0.89441119, 0.43267711, 0.30990133])
randn(n)
:产生个数为n的标准正态分布随机数
In [57]: np.random.randn(10)
Out[57]:
array([-1.07608846, -0.88521711, 0.53930381, 0.77248565, -1.08053865,
-1.04894814, 1.17795406, -1.58509011, 0.94604111, 0.47238522])
permutation(x)
:对数据x进行随机排列
In [58]: np.random.permutation((1,2,4,5,6))
Out[58]: array([2, 5, 4, 1, 6])
binomial(n,p,s)
:生成s个参数为n和p的二项分布
In [59]: np.random.binomial(10,0.5,10)
Out[59]: array([5, 3, 5, 7, 6, 5, 5, 8, 3, 7])
poisson(lambda,s)
:生成s个参数为lambda的泊松分布随机数
In [60]: np.random.poisson(2,5)
Out[60]: array([3, 2, 1, 1, 3])
normal(mu,sigma,s)
生成s个均值为mu,方差为sigma的正态分布随机数
In [61]: np.random.normal(10,5,10)
Out[61]:
array([ 3.16270262, 3.36088429, 16.03967109, 9.47283597, 17.73490876,
8.07676842, 11.98387286, 12.5266739 , 7.23715431, 6.58819786])
chisqure(df,s)
:生成s个自由度为df的卡方分布随机数
In [62]: np.random.chisquare(10,5)
Out[62]: array([10.54537798, 15.45366609, 12.46449898, 3.32914182, 5.80333844])
exponential(beta,s)
:生成s个参数为beta的指数分布随机数
In [63]: np.random.exponential(2,5)
Out[63]: array([1.841277 , 0.10434423, 0.54741996, 0.90809302, 3.35438231])
f(dfnum,dfden,s)
:生成s个自由度为dfnum和dfden的F分布随机变量
In [64]: np.random.f(2,5,3)
Out[64]: array([3.07168471, 0.20399149, 0.03073576])
gamma(alpha,beta,s)
:生成s个参数为alpha和beta的Gamma分布随机数
In [65]: np.random.gamma(1,2,3)
Out[65]: array([0.35356705, 2.47014576, 1.51165879])
8.6 例子
做标准正态分布随机数的直方图。
我们生成10000标准正态分布随机数,利用直方图来模拟标准正态分布的密度函数图像
In [66]: import matplotlib.pyplot as plt
In [67]: normal1 = np.random.randn(10000)
In [68]: plt.hist(normal1,bins = 50)
In [69]: plt.show()
得到的结果如下: