pattern and speech recognition的课要用到tensorflow,就打算学tensorflow,看到Get started中的例子需要用到numpy,要不就简单地先看一下numpy。
What’s numpy
numpy主要用于处理矩阵的科学计算。
—fixed size at creation
—python的语言,C的速度
—broadcast, element-by-element behavior
when operating on 2 arrays, numpy compare their shapes element-wise.
shape
shape: (a1,a2,a3,…), 表示有几个维度,数字表示该维度上的长度。 例:(4,1), 两个维度,第一维度长度为4,即为4行,第二长度维度是1,即为1列,就是4行1列的矩阵
broadcast rules
2个维度是可比较的:相等 or 其中一个长度为1
当其中一个长度为1,另一个对应维度长度为d时,运算操作会将矩阵扩展,结果取较大的长度d,例子如下:
>>> import numpy as np
>>> y = np.ones(5)
>>> y
array([ 1., 1., 1., 1., 1.])
>>> x = np.arange(4)
>>> x
array([0, 1, 2, 3])
>>> xx = x.reshape(4,1)
>>> xx
array([[0],
[1],
[2],
[3]])
>>> xx+y
array([[ 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2.],
[ 3., 3., 3., 3., 3.],
[ 4., 4., 4., 4., 4.]])
>>> (xx+y).shape
(4, 5)
维度不可比较(报错,无法计算)的例子:
>>> x = np.ones((2,1))
>>> y = np.zeros((8,4,3))
>>> x + y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (2,1) (8,4,3)
quick start tutorial
基本操作
numpy中,维度称为轴(axes), 维数称为秩(rank),numpy中的数组类名为ndarray,以下是ndarray的一些属性:
>>> x = np.array([[1,2,1],[3,5,6]])
>>> x
array([[1, 2, 1],
[3, 5, 6]])
>>> x.ndim
2
>>> x.shape
(2, 3)
>>> x.size
6
>>> x.dtype
dtype('int64')
>>> x.dtype.name
'int64'
>>> type(x)
<type 'numpy.ndarray'>
>>> x.itemsize
8
全0,全1或者empty数组(值随机),可用于初始化大小已知但数值未知的对象:
>>> ones = np.ones((3,4),dtype=np.int64)
>>> ones
array([[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]])
>>> zeros = np.zeros((3,4))
>>> zeros
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
>>> em = np.empty((2,3))
>>> em
array([[ 0., 0., 0.],
[ 0., 0., 0.]])
arange可用于生成数列:
>>> np.arange(10,30,5)
array([10, 15, 20, 25])
算术操作是element-wise的,作用在单个元素上
>>> a = np.array( [20,30,40,50] )
>>> b = np.arange( 4 )
>>> b
array([0, 1, 2, 3])
>>> c = a-b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> 10*np.sin(a)
array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854])
>>> a<35
array([ True, True, False, False], dtype=bool)
乘法符号 * 也是作用与单个元素上,执行矩阵乘法要使用dot函数
>>> A = np.array([[1,2],[8,0]])
>>> B = np.array([[3,0],[5,6]])
>>> A
array([[1, 2],
[8, 0]])
>>> B
array([[3, 0],
[5, 6]])
>>> A*B
array([[ 3, 0],
[40, 0]])
>>> A.dot(B)
array([[13, 12],
[24, 0]])
数据类型:精度高的不能转换精度低的,两个精度不同的矩阵进行运算,运算结果类型取精度高的
>>> a = np.ones((2,3), dtype=int)
>>> b = np.random.random((2,3))
>>> a+=b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Cannot cast ufunc add output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
>>> c = a+b
>>> c
array([[ 1.22483735, 1.39092262, 1.81829782],
[ 1.70122655, 1.51918794, 1.84569808]])
>>> c.dtype
dtype('float64')
ndarry类型的方法包括一元矩阵运算,如计算矩阵中所有元素和,最大最小值
>>> a = np.random.random((2,3))
>>> a
array([[ 0.18626021, 0.34556073, 0.39676747],
[ 0.53881673, 0.41919451, 0.6852195 ]])
>>> a.sum()
2.5718191614547998
>>> a.min()
0.1862602113776709
>>> a.max()
0.6852195003967595
使用axis参数可以对指定的维度进行一元运算
>>> b = np.arange(12).reshape(3,4)
>>> b
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b.sum(axis=0) #每一列的和
array([12, 15, 18, 21])
>>>
>>> b.min(axis=1) #每一行的最小元素
array([0, 4, 8])
索引,切分与迭代
一维:可以像list一样按下标索引元素
>>> a = np.arange(10)**3
>>> a
array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729])
>>> a[2]
8
>>> a[2:5]
array([ 8, 27, 64])
>>> a[:6:2] = -1000 # 从下标0到下标6迭代,步长2
>>> a
array([-1000, 1, -1000, 27, -1000, 125, 216, 343, 512, 729])
>>> a[ : :-1] # reversed a
array([ 729, 512, 343, 216, 125, -1000, 27, -1000, 1, -1000])
多维:形式一样,只是下标多了几个
shape 操作
numpy.reshape(): 不改变数据,改变维数和长度
>>> a = np.floor(10*np.random.random((3,4)))
>>> a
array([[ 5., 4., 0., 8.],
[ 9., 1., 7., 9.],
[ 0., 2., 4., 8.]])
>>> a.reshape((2,6))
array([[ 5., 4., 0., 8., 9., 1.],
[ 7., 9., 0., 2., 4., 8.]])
复制和views
不复制:简单赋值及函数调用不复制数据,改变其属性会改变原来矩阵属性,相当于指向同一个地方的指针
>>> a = np.arange(12)
>>> b = a # no new object is created
>>> b is a # a and b are two names for the same ndarray object
True
>>> b.shape = 3,4 # changes the shape of a
>>> a.shape
(3, 4)
view或swallow copy:view,创建一个新的对象,数据为a的数据,改变shape属性时a不改变,但是改变数据时a的数据也改变
>>> c = a.view()
>>> c
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> id(a)
139709095931616
>>> id(b)
139709095931616
>>> id(c)
139709095931536
>>> c.shape = 2,6
>>> c
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> c[0,4]=1234
>>> c
array([[ 0, 1, 2, 3, 1234, 5],
[ 6, 7, 8, 9, 10, 11]])
>>> a
array([[ 0, 1, 2, 3],
[1234, 5, 6, 7],
[ 8, 9, 10, 11]])
deep copy: 创建新的对象,改变属性或者数据时a的属性和对象都不变
>>> d = a.copy()
>>> id(d)
139709095931216
>>> d[0,0]=1111
>>> d
array([[1111, 1, 2, 3],
[1234, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a
array([[ 0, 1, 2, 3],
[1234, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> d.shape = 2,6
>>> d
array([[1111, 1, 2, 3, 1234, 5],
[ 6, 7, 8, 9, 10, 11]])
>>> a
array([[ 0, 1, 2, 3],
[1234, 5, 6, 7],
[ 8, 9, 10, 11]])
线性代数
转置:np.transpose()
k阶I矩阵:np.eye(k)
求逆:np.linalg.inv(a)
特征值与特征向量: np.linalg.eig(j)
>>> a = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> a.transpose()
array([[ 1., 3.],
[ 2., 4.]])
>>> np.linalg.inv(a)
array([[-2. , 1. ],
[ 1.5, -0.5]])
>>> u = np.eye(2) # unit 2x2 matrix; "eye" represents "I"
>>> u
array([[ 1., 0.],
[ 0., 1.]])
>>> j = np.array([[0.0, -1.0], [1.0, 0.0]])
>>> np.linalg.eig(j)
(array([ 0.+1.j, 0.-1.j]), array([[ 0.70710678+0.j , 0.70710678-0.j ],
[ 0.00000000-0.70710678j, 0.00000000+0.70710678j]]))