1. 安装方法
pip install numpy
2. 基本功能
>>> import numpy as np
>>> a = np.arange(15).reshape(3, 5)
# arange需要整理的数据集大小 reshape整理成几行几列
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
# 输入a,直接整理成从0递增的三行五列数据
>>> a.shape # a的格式 三行五列
(3, 5)
>>> a.ndim # a的维数 2
>>> a.dtype.name #dtype表示数组a内元素类型
'int64'
>>> a.itemsize # 数组中每个元素占几位 8
>>> a.size # a的大小 15
3. 构造数组
(1)使用array函数
# 生成一维数组
>>> a = np.array([2,3,4])
>>> a
array([2, 3, 4])
# 生成二维数组,注意中括号和小括号
>>> b = np.array([(1.5,2,3), (4,5,6)])
>>> b
array([[ 1.5, 2. , 3. ],
[ 4. , 5. , 6. ]])
# 生成复杂数组,类型提前声明,注意括号
>>> c = np.array( [ [1,2], [3,4] ], dtype=complex )
>>> c
array([[ 1.+0.j, 2.+0.j],
[ 3.+0.j, 4.+0.j]])
(2)生成零数组zeros,一数组ones,空数组empty
>>> np.zeros( (3,4) )
array([[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
(3)arange生成数字序列
# 顺序递增序列
d = np.arange(15)
d
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
#开始10,结束30,步长5
#注意:不包括30
>>> np.arange( 10, 30, 5 )
array([10, 15, 20, 25])
(4)linspace
>>> a = np.linspace(1,10) # 不设置数量,默认生成50个元素
>>> a
array([ 1. , 1.18367347, 1.36734694, 1.55102041, 1.73469388,
1.91836735, 2.10204082, 2.28571429, 2.46938776, 2.65306122,
2.83673469, 3.02040816, 3.20408163, 3.3877551 , 3.57142857,
3.75510204, 3.93877551, 4.12244898, 4.30612245, 4.48979592,
4.67346939, 4.85714286, 5.04081633, 5.2244898 , 5.40816327,
5.59183673, 5.7755102 , 5.95918367, 6.14285714, 6.32653061,
6.51020408, 6.69387755, 6.87755102, 7.06122449, 7.24489796,
7.42857143, 7.6122449 , 7.79591837, 7.97959184, 8.16326531,
8.34693878, 8.53061224, 8.71428571, 8.89795918, 9.08163265,
9.26530612, 9.44897959, 9.63265306, 9.81632653, 10. ])
>>> b = np.linspace(1,10,10) # 前两个参数是第一个和最后一个数据,第三个参数为元素个数
>>> b
array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])
>>> c = np.linspace(1,10,num=10,retstep=True) # retstep 显示等差数列,步长
>>> c
(array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.]), 1.0)
>>> d = np.linspace( 0, 2*3.14, 10 ) #参数可以为函数
>>> d
array([0. , 0.69777778, 1.39555556, 2.09333333, 2.79111111,
3.48888889, 4.18666667, 4.88444444, 5.58222222, 6.28 ])
(5)随机数 random
>>> np.random.rand(3,2)
array([[ 0.14022471, 0.96360618],
[ 0.37601032, 0.25528411],
[ 0.49313049, 0.94909878]])
4. 数组的输出
# 三维数组的输出
>>> c = np.arange(24).reshape(2,3,4)
# reshape的理解:第3个维度是4,里面有4个数据;
第2个维度是3,里面有3个包含4个数据的数组
第1个维度是2,里面有2个三行四列的矩阵
>>> print(c)
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]]
5. 主要操作
(1)点乘和叉乘
>>> A = np.array( [[1,1],
... [0,1]] )
>>> B = np.array( [[2,0],
... [3,4]] )
# 对应元素直接相乘
>>> A*B
array([[2, 0],
[0, 4]])
# 矩阵乘法
>>> A.dot(B)
array([[5, 4],
[3, 4]])
>>> np.dot(A, B)
array([[5, 4],
[3, 4]])
ps:doc()用法
array([[1, 2],
[3, 4]])
>>> b = np.arange(5,9).reshape(2,2)
>>> b
array([[5, 6],
[7, 8]])
>>> np.dot(a,b)
array([[19, 22],
[43, 50]])
所得到的数组中的每个元素为,第一个矩阵中与该元素行号相同的元素与第二个矩阵与该元素列号相同的元素,两两相乘后再求和。
dot()函数可以通过numpy库调用,也可以由数组实例对象进行调用。a.dot(b) 与 np.dot(a,b)效果相同。
矩阵积计算不遵循交换律,np.dot(a,b) 和 np.dot(b,a) 得到的结果是不一样的。
(2)求最大max、最小min、求和sum
在整个数组范围中求
>>> 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
在某个维度求和
>>> 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])
>>> b.cumsum(axis=1) # 每行逐次求和
array([[ 0, 1, 3, 6],
[ 4, 9, 15, 22],
[ 8, 17, 27, 38]])
(3)mean()
x = np.array([1,2,3,4,5])
y = np.array([0,2,3,4,6])
z = np.array([[1,2],[3,4]])#二维数组
np.mean(x==y)#返回条件成立的占比
Out[5]: 0.59999999999999998
np.mean(x)#均值
Out[6]: 3.0
np.mean(z)
Out[10]: 2.5
np.mean(z,axis=0)#按列求均值
Out[11]: array([ 2., 3.])
np.mean(z,axis=1)#按行求均值
Out[12]: array([ 1.5, 3.5])
6. 常用函数
aqrt、exp、sort...
7. 索引、切片、正则化
多维操作和一维操作相似
>>> def f(x,y):
... return 10*x+y
...
>>> b = np.fromfunction(f,(5,4),dtype=int)
>>> b
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33],
[40, 41, 42, 43]])
# 每个位置对应的值进行函数处理,b[2,3]=10*1+2
# 输出第2行,第3列的数
>>> b[2,3]
# 输出第0-5行(不包括第5行),第1列的数
>>> b[0:5, 1]
array([ 1, 11, 21, 31, 41])
# 输出所有行,第1列的数
# :表示所有
>>> b[ : ,1]
array([ 1, 11, 21, 31, 41])
# 输出1-3行(不包括第3行),所有数
>>> b[1:3, : ]
array([[10, 11, 12, 13],
[20, 21, 22, 23]])
# 输出最后一行
>>> b[-1]
array([40, 41, 42, 43])
# 第二,三,五行所有数据,用[1,2,4]表示
>>> b[[1,2,4],:]
array([[10, 11, 12, 13],
[20, 21, 22, 23],
[40, 41, 42, 43]])
...的用法
>>> c = np.array( [[[ 0, 1, 2], # c是三维数组
... [ 10, 12, 13]],
... [[100,101,102],
... [110,112,113]]])
>>> c.shape
(2, 2, 3)
>>> c[1,...] # 相当于 c[1,:,:] or c[1]
array([[100, 101, 102],
[110, 112, 113]])
>>> c[...,2] # 相当于 c[:,:,2]
array([[ 2, 13],
[102, 113]])
对行操作和对单个元素操作flat
# 对行进行操作
>>> for row in b:
... print(row)
...
[0 1 2 3]
[10 11 12 13]
[20 21 22 23]
[30 31 32 33]
[40 41 42 43]
# 对每个元素进行操作
>>> for element in b.flat:
... print(element)
...
1
3
11
13
21
23
31
33
41
43
8. 矩阵形状操作
shape 重设矩阵形状,(列,行)
ravel 将矩阵拉直成一维数组
转置T
>>> a = np.floor(10*np.random.random((3,4)))
>>> a
array([[ 2., 8., 0., 6.],
[ 4., 5., 1., 1.],
[ 8., 9., 3., 6.]])
>>> a.shape
(3, 4)
>>> a.ravel() # 拉成一维的了
array([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.])
>>> a.flatten() # 拉成一维的了
array([ 2., 8., 0., 6., 4., 5., 1., 1., 8., 9., 3., 6.])
#flatten 返回的是真实的数组,需要分配新的内存空间。而ravel 返回的是数组的视图
>>> a.reshape(6,2) # 重新设定形状 若把2改为-1,则会自动计算
array([[ 2., 8.],
[ 0., 6.],
[ 4., 5.],
[ 1., 1.],
[ 8., 9.],
[ 3., 6.]])
#改变 a 本身的数组,会改变所作用的数组,并且不能赋值,只作用于自身
>>> a.resize(2,6)
>>> a
array([[9., 2., 8., 2., 2., 1.],
[0., 1., 5., 3., 5., 9.]])
>>> b = a.resize(6,2)
>>> b
>>> a.T
>>> a.T
array([[9., 8., 2., 0., 5., 5.],
[2., 2., 1., 1., 3., 9.]])
9.矩阵堆叠
多维操作时,hstack沿着第二维堆叠,vstack沿着第一维堆叠,
并且有可选参数来控制沿着哪个维度堆叠。
>>> a = np.floor(10*np.random.random((2,2)))
>>> a
array([[ 8., 8.],
[ 0., 0.]])
>>> b = np.floor(10*np.random.random((2,2)))
>>> b
array([[ 1., 8.],
[ 0., 4.]])
# 竖着堆
>>> np.vstack((a,b))
array([[ 8., 8.],
[ 0., 0.],
[ 1., 8.],
[ 0., 4.]])
#横着堆
>>> np.hstack((a,b))
array([[ 8., 8., 1., 8.],
[ 0., 0., 0., 4.]])
# column_stack直接使用
>>> a=[[1,2,3],[10,20,30]]
>>> b=[[11,22,33],[110,220,330]]
>>> np.column_stack((a,b))
array([[ 1, 2, 3, 11, 22, 33],
[ 10, 20, 30, 110, 220, 330]])
>>> a=[1,2,3]
>>> b=[4,5,6]
>>> np.r_[a,b]
array([1, 2, 3, 4, 5, 6])
>>> np.c_[a,b]
array([[1, 4],
[2, 5],
[3, 6]])
>>> a=np.arange(15).reshape(3,5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> b=np.arange(15,0,-1).reshape(3,5)
>>> b
array([[15, 14, 13, 12, 11],
[10, 9, 8, 7, 6],
[ 5, 4, 3, 2, 1]])
>>> np.r_[a,b]
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 14, 13, 12, 11],
[10, 9, 8, 7, 6],
[ 5, 4, 3, 2, 1]])
>>> np.c_[a,b]
array([[ 0, 1, 2, 3, 4, 15, 14, 13, 12, 11],
[ 5, 6, 7, 8, 9, 10, 9, 8, 7, 6],
[10, 11, 12, 13, 14, 5, 4, 3, 2, 1]])
# 简单地总结一下用法就是:
np.r_是按行连接两个矩阵,就是把两矩阵上下相加,要求行数相等,类似于pandas中的concat()
np.c_是按列连接两个矩阵,就是把两矩阵左右相加,要求列数相等,类似于pandas中的merge()
10. 分割数组
横向数着切hsplit、纵向数着切vsplit
>>> a = np.floor(10*np.random.random((2,12)))
>>> a
array([[ 9., 5., 6., 3., 6., 8., 0., 7., 9., 7., 2., 7.],
[ 1., 4., 9., 2., 2., 1., 0., 6., 2., 2., 4., 0.]])
>>> np.hsplit(a,3) # 切成三个数组
[array([[ 9., 5., 6., 3.], [ 1., 4., 9., 2.]]),
array([[ 6., 8., 0., 7.], [ 2., 1., 0., 6.]]),
array([[ 9., 7., 2., 7.], [ 2., 2., 4., 0.]])]
>>> np.hsplit(a,(3,4)) # 第三列和第四列后面切一刀
[array([[ 9., 5., 6.], [ 1., 4., 9.]]),
array([[ 3.], [ 2.]]),
array([[ 6., 8., 0., 7., 9., 7., 2., 7.], [ 2., 1., 0., 6., 2., 2., 4., 0.]])]
>>> a=np.arange(24).reshape(4,6)
>>> a
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
>>> np.vsplit(a,2)
[array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]]), array([[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])]
>>> np.vsplit(a,(2,3))
[array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]]), array([[12, 13, 14, 15, 16, 17]]), array([[18, 19, 20, 21, 22, 23]])]
11.拷贝
操作数组时,有时候拷贝了副本,有时候没有,如何区分这些情况。
(1)不拷贝
简单的赋值
函数调用
(2)浅拷贝
view生成一个数据相同的新数组。
>>> a=np.arange(12).reshape(3,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> c = a.view()
>>> c is a # c和a是同一个数组
False
>>> c.base is a #c是a持有数据的镜像
True
>>> c.flags.owndata
False
>>> c.shape = 2,6 # 改变c的形状,a的形状没变
>>> a.shape
(3, 4)
>>> c[0,4] = 1234 #改变c的数据,a的数据改变
>>> a
array([[ 0, 1, 2, 3],
[1234, 5, 6, 7],
[ 8, 9, 10, 11]])
数据切片后返回浅拷贝,原始数据不受损
(3)深拷贝
copy完全拷贝数组和数据
>>> d = a.copy()
>>> d is a
False
>>> d.base is a # d和a没有关系
False
12. 索引
>>> a = np.arange(12)**2
>>> a
array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121])
>>> i = np.array( [ 1,1,3,8,5 ] )
>>> a[i] # 输出的是数组a中第i个位置中的数
array([ 1, 1, 9, 64, 25])
#若a是多维的,则索引指向它的第一维
#索引可以是多维的,索引的每一维必须形状相同
#利用索引来选择数组
>>> a = np.arange(12).reshape(3,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> b1 = np.array([False,True,True])
>>> b2 = np.array([True,False,True,False])
# 选择行
>>> a[b1,:]
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> a[b1]
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
# 选择列
>>> a[:,b2]
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
# 选择行列
>>> a[b1,b2]
array([ 4, 10])
ix_()函数 为了方便计算使用
可以为了获得多元组的结果而用来结合不同向量。例如,如果你想要用所有向量a、b和c元素组成的三元组来计算a+b*c
:
>>> a = np.array([2,3,4,5])
>>> b = np.array([8,5,4])
>>> c = np.array([5,4,6,8,3])
>>> ax,bx,cx = np.ix_(a,b,c)
>>> ax
array([[[2]],
[[3]],
[[4]],
[[5]]])
>>> bx
array([[[8],
[5],
[4]]])
>>> cx
array([[[5, 4, 6, 8, 3]]])
>>> ax.shape, bx.shape, cx.shape
((4, 1, 1), (1, 3, 1), (1, 1, 5))
>>> result = ax+bx*cx
>>> result
array([[[42, 34, 50, 66, 26],
[27, 22, 32, 42, 17],
[22, 18, 26, 34, 14]],
[[43, 35, 51, 67, 27],
[28, 23, 33, 43, 18],
[23, 19, 27, 35, 15]],
[[44, 36, 52, 68, 28],
[29, 24, 34, 44, 19],
[24, 20, 28, 36, 16]],
[[45, 37, 53, 69, 29],
[30, 25, 35, 45, 20],
[25, 21, 29, 37, 17]]])
>>> result[3,2,4]
>>> a[3]+b[2]*c[4]
13. 线性代数
>>> a = np.array([[1.0, 2.0], [3.0, 4.0]])
>>> print(a)
[[ 1. 2.]
[ 3. 4.]]
>>> a.transpose() # 转置
array([[ 1., 3.],
[ 2., 4.]])
>>> np.linalg.inv(a) # 取反
array([[-2. , 1. ],
[ 1.5, -0.5]])
>>> u = np.eye(2) # 单位阵
>>> u
array([[ 1., 0.],
[ 0., 1.]])
>>> j = np.array([[0.0, -1.0], [1.0, 0.0]])
>>> np.dot (j, j) # 矩阵间相乘
array([[-1., 0.],
[ 0., -1.]])
>>> y = np.array([[5.], [7.]])
>>> np.linalg.solve(a, y) # 解方程
array([[-3.],
[ 4.]])