In [1]:
# 引入所有必要的模块
%matplotlib inline
import matplotlib.pyplot as plt
from IPython.core.display import Image, display
import numpy as np
NumPy is the fundamental package for scientific computing with Python. It contains among other things:
(from Wikipedia)
1. Array and the axis in numpy
In [2]:
display(Image(filename='figures/axes.png', width=720))
可以这样想象及可视化更高维度的数组:
更高维度的,可以依次类推进行想象及可视化。
In [3]:
display(Image(filename='figures/tensors.png', width=720))
2. 创建array及array基本特性
主要创建方式:
2.1 由list/tuple创建
In [4]:
v = np.array([1,2,3,4])
v
Out[4]:
一维list对应一维array
In [5]:
M = np.array([[1, 2], [3, 4]])
M
Out[5]:
Matrix(矩阵),也即2维数组,对应二维list
In [6]:
type(v), type(M)
Out[6]:
利用type()函数,可知v,M是numpy中的ndarray类型(n dimension array)
In [7]:
v.shape
Out[7]:
In [8]:
v.size
Out[8]:
In [9]:
M.shape
Out[9]:
In [10]:
M.size
Out[10]:
In [11]:
M.itemsize
Out[11]:
每个元素字节数
In [12]:
M.nbytes
Out[12]:
总字节数(number of bytes)
In [13]:
M.ndim
Out[13]:
数组维数
In [14]:
M.dtype
Out[14]:
In [15]:
M = np.array([[1, 2], [3, 4]], dtype=complex)
M
Out[15]:
In [16]:
M.astype(float)
Out[16]:
元素类型可以由astype()函数改变
2.2 由numpy内置函数创建
In [17]:
x = np.arange(0, 10, 1) #:start, stop, step
x
Out[17]:
依旧是左闭右开[)
In [18]:
x = np.arange(-1, 1, 0.2)
x
Out[18]:
In [19]:
x = np.linspace(0, 10, 25)#:start, end, number
x
Out[19]:
In [20]:
xe = np.logspace(0, 10, 25, base=np.e)
xe
Out[20]:
In [21]:
plt.plot(xe);
In [22]:
plt.plot(np.exp(x));
In [23]:
x = np.random.rand(25)
x
Out[23]:
利用numpy的random下的rand()函数,得到在[0,1]之间的随机数1维数组(随机数以均匀分布的方式生成,分布的均值为0.5)
In [24]:
x= np.random.randn(5,5)
x
Out[24]:
利用numpy的random下的randn()函数,得到随机数2维数组(随机数以标准正态分布的方式生成,分布的期望/均值为0,方差为1)
In [25]:
np.eye(5)
Out[25]:
单位阵
In [26]:
np.diag([2,3,4,5])
Out[26]:
对角阵
In [27]:
np.diag([1,2,3,4], k=1)
Out[27]:
带偏移量的特殊对角阵
In [28]:
np.zeros([5,5])
Out[28]:
零矩阵
In [29]:
np.ones([5,5])
Out[29]:
全一矩阵
2.3 读入文件时创建
In [30]:
data = np.genfromtxt('stockholm_td_adj.dat')
data[:5]
Out[30]:
这两种形式存放的文件可以直接利用genfromtxt()函数读入并自动成为array类型。
In [31]:
data.shape
Out[31]:
In [32]:
M = np.random.rand(3,3)
M
Out[32]:
In [33]:
np.savetxt("random-matrix.csv", M)
!type random-matrix.csv
In [34]:
np.savetxt("random-matrix.csv", M, fmt='%.5f')
!type random-matrix.csv
利用savetxt()函数的fmt参数,控制保存精度
In [35]:
np.save("random-matrix.npy", M)
In [36]:
np.load("random-matrix.npy")
Out[36]:
如果不需要利用编辑器来查看保存文件的内容,也可以利用save()及load()函数存取array为npy格式。
3. 数组基本操作
3.1 索引及切片
In [37]:
v
Out[37]:
In [38]:
v[0]
Out[38]:
In [39]:
M
Out[39]:
In [40]:
M[1,1]
Out[40]:
In [41]:
M[1]
Out[41]:
取第0轴的第1行
In [42]:
M[1,:]
Out[42]:
M[1,:]与M[1]是一样的功能。完整格式为M[a,b],当只有M[a]时,即在0轴a行上,其他维度所有值均被选择
In [43]:
M[:,1]
Out[43]:
第1列,即0轴方向元素均选取,1轴方向取第1列
In [44]:
M[1,0] = 1
M
Out[44]:
In [45]:
M[1,:] = 2
M[:,2] = 10
M
Out[45]:
In [46]:
v
Out[46]:
In [47]:
v[-1]
Out[47]:
In [48]:
v[-3:]
Out[48]:
In [49]:
v[1:3]
Out[49]:
In [50]:
v[1:3] = [5,7]
v
Out[50]:
In [51]:
A = np.array([[n + m * 10 for n in range(5)] for m in range(5)])
A
Out[51]:
一样可以使用类似列表解析的方法
In [52]:
A[1:4, 1:4]
Out[52]:
取矩阵中的一个区域
3.2 花式索引(Fancy indexing)
In [53]:
A = np.random.randn(5,5)
A
Out[53]:
In [54]:
row_indices = [1, 2, 3]
A[row_indices]
Out[54]:
In [55]:
col_indices = [1, 2, -1]
A[row_indices, col_indices]
Out[55]:
In [56]:
A = np.arange(0,10,0.5)
A
Out[56]:
In [57]:
indices = np.array([[2,3],[7,8]])
A[indices]
Out[57]:
还可以利用array对象作为索引进行数据选择,当索引是二维array时,选择结果的array的维度与索引array维度相同
In [58]:
B = np.array([n for n in range(6)])
B
Out[58]:
In [59]:
mask = B >= 3
mask
Out[59]:
array类型可以直接与数字进行逻辑比较,返回一个元素都是布尔值的array
In [60]:
B[mask]
Out[60]:
布尔值array可以作为同样维度大小的array的蒙版/掩码,以屏蔽一些元素(对象False位置)
In [61]:
A = np.arange(0,10,0.5)
A
Out[61]:
In [62]:
mask = np.logical_and(A>5, A<10)
mask
Out[62]:
logical_and()来进行array的逻辑与运算
In [63]:
A[mask]
Out[63]:
利用mask进行数据选择
In [64]:
A[[1,2,3]] = 9,9,9
A
Out[64]:
可以直接对选择的数据进行赋值
where
In [65]:
mask
Out[65]:
In [66]:
indices = np.where(mask)
indices
Out[66]:
利用where()函数,取得mask数组选取值的索引
In [67]:
A
Out[67]:
In [68]:
A[indices]
Out[68]:
与直接使用mask进行数据选择的效果相同
diag
In [69]:
A=np.random.randn(5,5)
A
Out[69]:
In [70]:
np.diag(A)
Out[70]:
利用diag()函数,取A的对角(默认为左上开始)
In [71]:
np.diag(A, 1)
Out[71]:
可以进行偏移后再选取对角元素
4. 线性代数
在数值计算以及深度学习中,向量化是非常关键的步骤,要尽量以向量进行表示与运算。
4.1 一般操作
In [72]:
v1 = np.arange(0, 5)
v1
Out[72]:
In [73]:
v1*10
Out[73]:
向量乘以标量,结果是每个元素都乘以标量
In [74]:
v1**3
Out[74]:
向量进行指数运算,结果是每个元素指数运算
In [75]:
v1*v1
Out[75]:
向量*向量,结果是两个向量中对应的元素相乘
In [76]:
v1**v1
Out[76]:
向量**向量,结果是对应元素进行指数运算
In [77]:
A = np.arange(25).reshape(5,5)
A
Out[77]:
In [78]:
A*10
Out[78]:
矩阵乘以标量,结果是每个元素乘以标量
In [79]:
A.shape, v1.shape
Out[79]:
In [80]:
A @ A
Out[80]:
矩阵点乘,与线性代数中矩阵点乘相同(python3.6或更高可用@)
In [81]:
A @ v1
Out[81]:
矩阵与向量点乘
In [82]:
v1 @ A
Out[82]:
点乘时,一维向量既可以作为行向量又可以作为列向量
In [83]:
v1 @ v1
Out[83]:
向量点乘
In [84]:
A.dot(A)
Out[84]:
对低版本的python,也可以利用点乘函数dot()
In [85]:
A.T
Out[85]:
二维数组转置
4.2 广播(Broadcasting)
In [86]:
display(Image(filename='figures/broadcast1.png', width=720))
In [87]:
display(Image(filename='figures/broadcast2.png', width=720))
In [88]:
A
Out[88]:
In [89]:
A+10
Out[89]:
In [90]:
v1
Out[90]:
In [91]:
A+v1
Out[91]:
In [92]:
display(Image(filename='figures/calories.png', width=720))
In [93]:
# 基于非广播的方式进行计算
macros = np.array([
[0.3, 2.5, 3.5],
[2.9, 27.5, 0],
[0.4, 1.3, 23.9],
[14.4, 6, 2.3]])
# 创建一个形状与macros相同的全零矩阵
result = np.zeros_like(macros)
cal_per_macro = np.array([9, 4, 4])
#对0轴循环,每行向量进行向量相乘
for i in range(macros.shape[0]):
result[i, :] = macros[i, :] * cal_per_macro
result
Out[93]:
In [94]:
macros*cal_per_macro
Out[94]:
矩阵与向量相乘可以直接利用广播方式,方法简洁快速
4.3 Matrix类型
以上运算的规律无论是向量和矩阵均为array类型,numpy也提供了基于一般线性代数运算规则的Matrix
In [95]:
M = np.matrix(A)
M
Out[95]:
利用matrix()函数可将array对象或list,tuple对象转换为matirx对象。
In [96]:
v = np.matrix(v1).T
v
Out[96]:
In [97]:
v.shape
Out[97]:
转置后,v为一个列向量
In [98]:
M * v
Out[98]:
矩阵乘以向量
In [99]:
v.T * v
Out[99]:
向量内积
In [100]:
M * M
Out[100]:
矩阵相乘
In [101]:
M = np.matrix([[2,3],[5,5]])
np.linalg.inv(M)
Out[101]:
linalg下的inv()函数,可以求矩阵的拟
In [102]:
M.I
Out[102]:
更方便的是使用matrix对象的I属性来求逆
In [103]:
np.linalg.det(M)
Out[103]:
可用linalg.det()来求matrix对象的行列式
5. 数据处理
In [104]:
data.shape
Out[104]:
In [105]:
data[:,3].mean() # np.mean(data[:,3])
Out[105]:
利用mean()函数计算第三列的均值
In [106]:
data[:,3].max()
Out[106]:
计算最大值
In [107]:
data[:,3].min()
Out[107]:
最小值
In [108]:
data[:,3].sum()
Out[108]:
求和
In [109]:
A
Out[109]:
In [110]:
A[1].prod()
Out[110]:
求积
In [111]:
A.cumsum()
Out[111]:
累加求和
In [112]:
A.max()
Out[112]:
全局最大值
In [113]:
A.max(axis=0)
Out[113]:
求0轴方向的向量的最大值
In [114]:
A.max(axis=1)
Out[114]:
求1轴方向的向量的最大值
6. 维度变化
In [115]:
A = np.random.randn(25)
B = A.reshape(5,5)
B
Out[115]:
利用reshape()函数将矩阵变形
In [116]:
A.shape
Out[116]:
In [117]:
B.shape
Out[117]:
In [118]:
A[1:4] = 5
A
Out[118]:
In [119]:
B
Out[119]:
B只是A的一个视图(view)应用,A与B指向同一个array,因此改变A,则B也会改变,反之亦然
In [120]:
A = B.copy()
B[0,:] = 10
A
Out[120]:
一般可利用copy()函数,制作一个副本,由于是复制了一个副本,因此B改变一般不会影响A
In [121]:
B = A.flatten()
B
Out[121]:
利用flattern()函数,将高维数组降维成1维向量
In [122]:
B[:5] = 10
A
Out[122]:
注意降维是新生成1维向量
In [123]:
a = np.array([
[[1,2],[3,4]],
[[2,3],[4,5]]
])
a.repeat(3) #np.repeat(a,3)
Out[123]:
重复每个数字三次形成一维数组
In [124]:
np.tile(a, 3) #注意,暂时不能a.tile(3)
Out[124]:
每个向量内重复三次,形成的数组维度保持不变
In [125]:
a = np.array([[1,2],[3,4]])
b = np.array([[5,6]])
np.concatenate((a, b), axis=0)
Out[125]:
按照0轴方向链接向量,1轴方向维度不变
In [126]:
np.concatenate((a, b.T), axis=1)
Out[126]:
按照1轴方向链接向量,0轴方向维度不变
In [127]:
np.vstack([a,b])
Out[127]:
竖向堆叠
In [128]:
np.hstack([a,b.T])
Out[128]:
横向堆叠