主要介绍Python中的Numpy入门教程,着重讲解了矩阵中的数组操作。
[TOC]
# Numpy是什么
NumPy是Python中的一个运算速度非常快的一个数学库,一般与Scipy、matplotlib一起使用,它非常重视数组。它允许你在Python中进行向量和矩阵计算,并且由于许多底层函数实际上是用C编写的,因此你可以体验在原生Python中永远无法体验到的速度。
> NumPy绝对是科学Python成功的关键之一,如果你想要进入Python中的数据科学和/或机器学习,你就要必须学习它。
在以下的代码示例中,总是先导入了numpy:
```
>>> import numpy as np
>>> print(np.version.version)
1.14.0
```
# 数组基础
NumPy围绕这些称为数组的事物展开,它被称之为`ndarrays`。使用NumPy提供的这些数组,我们就可以以闪电般的速度执行各种有用的操作,如矢量和矩阵、线性代数等数学运算!,
> 多维数组的类型是:`numpy.ndarray`。
```
>>>data = [1,2,3,4]
>>>print(type(data))
<class 'list'>
>>>array=np.array(data)
>>>print(type(array))
<class 'numpy.ndarray'>
```
## 使用NumPy表示向量
以list或tuple变量为参数产生一维数组:
```
>>> print(np.array([1,2,3,4]))
[1 2 3 4]
>>> print(np.array((1.2,2,3,4)))
[ 1.2 2. 3. 4. ]
>>> print(type(np.array((1.2,2,3,4))))
<type 'numpy.ndarray'>
```
~~~
# 1D Array
a = np.array([0, 1, 2, 3, 4])
b = np.array((0, 1, 2, 3, 4))
c = np.arange(5)
d = np.linspace(0, 2*np.pi, 5)
print(a) # >>>[0 1 2 3 4]
print(b) # >>>[0 1 2 3 4]
print(c) # >>>[0 1 2 3 4]
print(d) # >>>[ 0. 1.57079633 3.14159265 4.71238898 6.28318531]
print(a[3]) # >>>3
~~~
上面的代码显示了创建数组的4种不同方法。最基本的方法是将序列传递给NumPy的array()函数; 你可以传递任何序列(类数组),而不仅仅是常见的列表(list)数据类型。
## 多维数组
以list或tuple变量为元素产生二维数组
~~~
# MD Array,
a = np.array([[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25],
[26, 27, 28 ,29, 30],
[31, 32, 33, 34, 35]])
print(a[2,4]) # >>>25
~~~
为了创建一个2D(二维)数组,我们传递一个列表的列表(或者是一个序列的序列)给array()函数。如果我们想要一个3D(三维)数组,我们就要传递一个列表的列表的列表,如果是一个4D(四维)数组,那就是列表的列表的列表的列表,以此类推。
> 请注意2D(二维)数组(在我们的朋友空格键的帮助下)是如何按行和列排列的。要索引2D(二维)数组,我们只需引用行数和列数即可。
生成数组的时候,可以指定数据类型,例如numpy.int32, numpy.int16, and numpy.float64等:
```
>>> print(np.array((1.2,2,3,4), dtype=np.int32))
[1 2 3 4]
```
> 浮点数转换int32类型时采用的是截尾操作。
# 常用函数
## 使用numpy.arange方法
```
>>> print(np.arange(15))
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
>>> print(type(np.arange(15)))
<class 'numpy.ndarray'>
```
```
>>> print(np.arange(15).reshape(3,5))
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]]
>>> print(type(np.arange(15).reshape(3,5)))
<class 'numpy.ndarray'>
```
## 使用numpy.linspace方法
例如,在从1到10中产生10个数:
```
>>> print(np.linspace(1,10,10))
[ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.]
```
## 使用numpy.zeros,numpy.ones,numpy.eye等方法可以构造特定的矩阵
```
>>> print(np.zeros((3,4)))
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
>>> print(np.ones((3,4)))
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
>>>print(np.eye(3))
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
```
创建一个三维数组:
```
>>>print(np.ones((3,4,5)))
[[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]
[[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]]]
```
## 获取数组的属性:
```
>>> a = np.zeros((2,2,2))
>>> print(a.ndim) #数组的维数
3
>>> print(a.shape) #数组每一维的大小
(2, 2, 2)
>>> print(a.size) #数组的元素数
8
>>> print(a.dtype) #元素类型
float64
>>> print(a.itemsize) #每个元素所占的字节数
8
```
## 数组索引,切片,赋值
```
>>> a = np.array( [[2,3,4],[5,6,7]] )
>>> print a
[[2 3 4]
[5 6 7]]
>>> print a[1,2]
7
>>> print a[1,:]
[5 6 7]
>>> print a[1,1:2]
[6]
>>> a[1,:] = [8,9,10]
>>> print a
[[ 2 3 4]
[ 8 9 10]]
```
## 使用for操作元素
```
>>> for x in np.linspace(1,3,3):
... print(x)
...
1.0
2.0
3.0
```
## 基本的数组运算
先构造数组a、b:
```
>>> a = np.ones((2,2))
>>> b = np.eye(2)
>>> print a
[[ 1. 1.]
[ 1. 1.]]
>>> print b
[[ 1. 0.]
[ 0. 1.]]
```
数组的加减乘除:
```
>>> print a > 2
[[False False]
[False False]]
>>> print a+b
[[ 2. 1.]
[ 1. 2.]]
>>> print a-b
[[ 0. 1.]
[ 1. 0.]]
>>> print b*2
[[ 2. 0.]
[ 0. 2.]]
>>> print (a*2)*(b*2)
[[ 4. 0.]
[ 0. 4.]]
>>> print b/(a*2)
[[ 0.5 0. ]
[ 0. 0.5]]
>>> print (a*2)**4
[[ 16. 16.]
[ 16. 16.]]
```
使用数组对象自带的方法:
```
>>> a.sum()
4.0
>>> a.sum(axis=0) #计算每一列(二维数组中类似于矩阵的列)的和
array([ 2., 2.])
>>> a.min()
1.0
>>> a.max()
1.0
```
使用numpy下的方法:
```
>>> np.sin(a)
array([[ 0.84147098, 0.84147098],
[ 0.84147098, 0.84147098]])
>>> np.max(a)
1.0
>>> np.floor(a)
array([[ 1., 1.],
[ 1., 1.]])
>>> np.exp(a)
array([[ 2.71828183, 2.71828183],
[ 2.71828183, 2.71828183]])
>>> np.dot(a,a) ##矩阵乘法
array([[ 2., 2.],
[ 2., 2.]])
```
## 合并数组
使用numpy下的vstack和hstack函数:
```
>>> a = np.ones((2,2))
>>> b = np.eye(2)
>>> print np.vstack((a,b))
[[ 1. 1.]
[ 1. 1.]
[ 1. 0.]
[ 0. 1.]]
>>> print np.hstack((a,b))
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]]
```
看一下这两个函数有没有涉及到浅拷贝这种问题:
```
>>> c = np.hstack((a,b))
>>> print(c)
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]]
>>> a[1,1] = 5
>>> b[1,1] = 5
>>> print(c)
[[ 1. 1. 1. 0.]
[ 1. 1. 0. 1.]]
```
可以看到,a、b中元素的改变并未影响c。
## 深拷贝数组
数组对象自带了浅拷贝和深拷贝的方法,但是一般用深拷贝多一些:
复制代码代码如下:
```
>>> a = np.ones((2,2))
>>> b = a
>>> b is a
True
>>> c = a.copy() #深拷贝
>>> c is a
False
```
## 基本的矩阵运算
转置:
```
>>> a = np.array([[1,0],[2,3]])
>>> print(a)
[[1 0]
[2 3]]
>>> print(a.transpose()
)
[[1 2]
[0 3]]
```
迹:
```
>>> print(np.trace(a)
)
4
```
numpy.linalg模块中有很多关于矩阵运算的方法:
```
>>> import numpy.linalg as nplg
```
特征值、特征向量:
```
>>> print(nplg.eig(a)
)
(array([ 3., 1.]), array([[ 0. , 0.70710678],
[ 1. , -0.70710678]]))
```