一、numpy简介
NumPy 是一个 Python 包, 它代表 “Numeric Python”。 它是一个由多维数组对象和用于处理数组的例程集合组成的库,支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。Numpy内部解除了Python的PIL(全局解释器锁),运算效率极好,是大量机器学习框架的基础库。
二、使用numpy创建数组
首先导入numpy
import numpy as np
1、使用np.array方法创建数组
a = np.array([1, 2, 3]) #一维数组
b = np.array([[1, 2, 3], [4, 5, 6]]) #二维数组
print a
print b
输出:
[1 2 3]
[[1 2 3]
[4 5 6]]
也可以直接将python列表或元组转换成numpy数组
a = [1, 2, 3, 4]
b = np.array(a)
print b
输出:
[1 2 3 4]
还可以使用np.zeros([m, n])或者np.ones([m, n])来创建值全为0或者全为1的m行n列的数组。
a = np.zeros([3, 4])
print a
输出:
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
b = np.ones([3, 4])
print b
输出:
[[1. 1. 1. 1.]
[1. 1. 1. 1.]
[1. 1. 1. 1.]]
可以看到上面的输出默认为float,若想得到int的输出,只要指定dtype参数为int即可
b = np.ones([3, 4], dtype=int)
print b
输出:
[[1 1 1 1]
[1 1 1 1]
[1 1 1 1]]
这样产生的是一个二维数组,有时候我们想要一维的初始化数组,使用以下方法即可:
b = np.ones([3, 4], dtype=int).flatten()
print b
输出:
[1 1 1 1 1 1 1 1 1 1 1 1]
除了使用np.array方法创建数组外,还可以使用np.asarray方法。两者的区别表现在当复制数组时,array方法为深复制,而asarray方法为浅复制。
a = np.zeros([3, 4])
b = np.array(a)
c = np.asarray(a)
d = a
a[0] = 1
print a
print '
'
print b
print '
'
print c
print '
'
print d
输出:
[[1. 1. 1. 1.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[1. 1. 1. 1.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
[[1. 1. 1. 1.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
2、使用np.arange方法创建数组
np.arange(start, stop, step, dtype)方法可以接收4个参数:start为数组范围的起始值,默认为0;stop为范围结束值的下一个值,也就是数组范围为[start, stop);step为产生数组的步长,默认为1;dtype为产生的数据类型。
a = np.arange(5) #只提供终止值
print a
输出:
[0 1 2 3 4]
a = np.arange(1, 10, 2) #提供起始值、终止值和步长
print a
输出:
[1 3 5 7 9]
3、使用np.linspace方法创建数组
np.linspace(start, stop, num, endpoint, retstep, dtype)可以接收5个参数:start和stop与np.arange相同;endpoint表示数据范围是否包括stop,若endpoint为true,则数据范围为[start, stop],否则为[start, stop),endpoint默认为true;num则表示在指定的数据范围内均匀地产生num个数,dtype指定了产生的数据类型。
a = np.linspace(1, 10, 5) #在[1, 10]之间均匀地产生5个数
print a
输出:
[ 1. 3.25 5.5 7.75 10. ]
a = np.linspace(1, 10, 5, endpoint=False) #在[1, 9]之间均匀地产生5个数
print a
输出:
[1. 2.8 4.6 6.4 8.2]
三、numpy基本操作
1、获取数组中的元素个数
import numpy as np
a = np.array([1, 2, 3]) #一维数组
b = np.array([[1, 2, 3], [4, 5, 6]]) #二维数组
print a.size
print b.size
输出:
3
6
2、获取数组形状(几行几列, 一维数组返回列数)
a = np.array([1, 2, 3]) #一维数组
b = np.array([[1, 2, 3], [4, 5, 6]]) #二维数组
print a.shape
print b.shape
输出:
(3L,)
(2L, 3L)
还可以用reshape函数调整数组形状
b = np.array([[1, 2, 3], [4, 5, 6]])
c = b.reshape(3, 2)
print c
输出
[[1 2]
[3 4]
[5 6]]
b通过reshape产生了一个3行2列的数组c.
3、获取数组维度
a = np.array([1, 2, 3]) #一维数组
b = np.array([[1, 2, 3], [4, 5, 6]]) #二维数组
print a.ndim
print b.ndim
输出:
1
2
四、numpy数组切片
numpy数组的切片与python列表切片类似,a[m:n]表示取下标在[m, n)之间的数据,a[m:]表示从下标m开始一直取到数组a的最后一个数据,a[:n]表示取下标在[0, n)之间的数据,a[:]表示数组a。
一维数组切片:
a = np.array([1, 2, 3, 4, 5])
b = a[1:4]
print b
c = a[1:]
print c
d = a[:3]
print d
e = a[:]
print e
输出:
[2 3 4] #b
[2 3 4 5] #c
[1 2 3] #d
[1 2 3 4 5] #e
二维数组切片:
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print a
b = a[1:2, 1:2]
print b
c = a[1:, :1]
print c
d = a[:, :]
print d
输出:
[[1 2 3] #a
[4 5 6]
[7 8 9]]
[[5]] #b
[[4] #c
[7]]
[[1 2 3] #d
[4 5 6]
[7 8 9]]
可以看到二维数组的切片分成了两个部分,用逗号分隔,第一部分表示行的范围,第二部分表示列的范围。
五、np.random的使用
1、使用np.random.rand(m, n)创建m行n列的数组,数组值范围为[0,1),不提供m和n则只产生一个随机数。
a = np.random.rand(5, 5)
print a
输出:
[[0.58217643 0.64383117 0.76970558 0.19093121 0.55160547]
[0.17104143 0.37784287 0.54680743 0.02004874 0.7704732 ]
[0.44994954 0.49856079 0.31035112 0.97869974 0.94965246]
[0.22002432 0.18942185 0.82604923 0.90411721 0.21349957]
[0.55091737 0.74666898 0.62638943 0.20161895 0.8862976 ]]
2、使用np.random.normal(loc=0.0, scale=1.0, size=None)来创建高斯分布的随机数,loc为均值,scale为标准差,size为创建的数组大小。
a = np.random.normal(0, 1, (3, 3))
print a
输出:
[[ 0.45019676 -2.03182249 -1.63827994]
[-1.24037828 0.86693021 -1.42478489]
[ 1.39990274 -0.6936522 1.6802083 ]]
3、使用numpy.random.randint(low, high=None, size=None, dtype='l')来产生指定范围内的整数,范围为[low, high),如果没有指定high,则范围为[0, low)。
a = np.random.randint(10, size=(3, 3))
print a
b = np.random.randint(5, 10, size=(3, 3))
print b
输出:
[[1 2 1]
[2 5 9]
[2 3 1]]
[[7 7 8]
[5 6 5]
[7 7 9]]
4、使用np.random.shuffle打乱数组
a = np.arange(10)
print a
np.random.shuffle(a)
print a
输出:
[0 1 2 3 4 5 6 7 8 9]
[4 7 9 6 8 2 5 3 1 0]
a = np.arange(9).reshape(3, 3)
print a
np.random.shuffle(a)
print a
输出:
[[0 1 2]
[3 4 5]
[6 7 8]]
[[3 4 5]
[0 1 2]
[6 7 8]]
5、使用numpy.random.choice(a, size=None, replace=True, p=None)对数组进行随机抽样,如果a是一个数组,则从a中抽取元素,若a是一个int值,则从np.arange(a)中抽取元素;size为抽取的元素形状,若为(m, n)则抽取m*n个元素,排成m行n列;当replace为False时,生成的随机数不能有重复的值;p代表了数组a中每个元素被抽取的概率,默认是从所有元素中随机抽取。
a = np.arange(5)
print a
b = np.random.choice(a, size=3, replace=False) # 从a中随机抽取3个数,不允许重复
print b
c = np.random.choice(a, size=10, p=(0.5, 0.1, 0.1, 0.1, 0.2)) # 从a中抽取10个数,[0 1 2 3 4]被抽取的概率分别为(0.5, 0.1, 0.1, 0.1, 0.2)
print c
[0 1 2 3 4]
[4 2 1]
[0 0 0 0 1 0 0 0 4 0]
六、numpy搜索和替换
1、条件计算
可以使用np.where函数找出数组a中元素值大于5的下表
a = np.arange(9).reshape(3, 3)
print a
b = np.where(a>5)
print b
输出:
[[0 1 2]
[3 4 5]
[6 7 8]]
(array([2, 2, 2], dtype=int64), array([0, 1, 2], dtype=int64))
将结果的第一个数组与第二个数据结合就可以得到值大于5的元素下标:[2, 0], [2, 1], [2, 2]。
2、替换
可以使用以下方法将数组中大于5的值替换为-1。
a = np.arange(9).reshape(3, 3)
print a
a[a>5] = -1
print a
输出:
[[0 1 2]
[3 4 5]
[6 7 8]]
[[ 0 1 2]
[ 3 4 5]
[-1 -1 -1]]
七、numpy统计函数
1、最大值与最小值
使用np.amax()和np.amin()来求数组中指定轴的最大值和最小值,在二维数组中,axis=0表示列,axie=1表示行。未指定轴则取数组内全部元素的最大值和最小值。
a = np.arange(9).reshape(3, 3)
print a
print np.amax(a)
print np.amin(a)
cmax = np.amax(a, axis=0) #列的最大值
rmin = np.amin(a, axis=1) #行的最小值
print cmax
print rmin
输出:
[[0 1 2]
[3 4 5]
[6 7 8]]
8
0
[6 7 8]
[0 3 6]
2、算数平均值
使用np.mean()求数组中指定轴的平均值,在二维数组中,axis=0表示列,axie=1表示行。未指定轴则对数组内全部元素取平均值。
a = np.arange(9).reshape(3, 3)
print a
cmean = np.mean(a, axis=0) #列的平均值
rmean = np.mean(a, axis=1) #行的平均值
print a_max
print a_min
输出:
[[0 1 2]
[3 4 5]
[6 7 8]]
[3. 4. 5.]
[1. 4. 7.]
3、加权平均值
np.average()用来计算加权平均值,也可以计算指定轴的加权平均值。
a = np.array([1, 2, 3])
print a
print np.average(a)
avg = np.average(a, weights=[6, 6, 6])
print avg
输出:
[1 2 3]
2.0
2.0
当未指定权重和轴时,np.average对数组中所有元素求平均值,当指定权重时,np.average求数组的加权平均值,上面的例子中,avg=(16+26+3*6)/(6+6+6)=2.0
4、方差
使用np.var()来计算方差,可通过axis参数指定轴。
a = np.arange(9).reshape(3, 3)
print a
print np.var(a)
cvar = np.var(a, axis=0) #列的方差
rvar = np.var(a, axis=1) #行的方差
print cvar
print rvar
输出:
[[0 1 2]
[3 4 5]
[6 7 8]]
6.666666666666667
[6. 6. 6.]
[0.66666667 0.66666667 0.66666667]
5、标准差
使用np.std()来计算标准差,如果没有指定轴,则在数组全部的值中计算。标准差是方差的平方根。
a = np.arange(9).reshape(3, 3)
print a
print np.std(a)
cstd = np.std(a, axis=0) #列的标准差
rstd = np.std(a, axis=1) #行的标准差
print cstd
print rstd
输出:
[[0 1 2]
[3 4 5]
[6 7 8]]
2.581988897471611
[2.44948974 2.44948974 2.44948974]
[0.81649658 0.81649658 0.81649658]
6、中位数
使用np.median()求中位数,可通过axis参数指定轴。
a = np.arange(9).reshape(3, 3)
print a
print np.median(a)
cmdn = np.median(a, axis=0) #列的中位数
rmdn = np.median(a, axis=1) #行的中位数
print cmdn
print rmdn
输出:
[[0 1 2]
[3 4 5]
[6 7 8]]
4.0
[3. 4. 5.]
[1. 4. 7.]
八、numpy线性代数
1、数组点积
可以使用np.dot(a, b)方法来求两个数组的点积。对于二维数组,其等效于矩阵乘法。 对于一维数组,它是向量的内积。 对于 N 维数组,它是a的最后一个轴上的和与b的倒数第二个轴的乘积。
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print np.dot(a, b)
c = np.array([1, 2, 3])
d = np.array([4, 5, 6])
print np.dot(c, d)
输出:
[[19 22]
[43 50]]
32
2、向量点积
可以使用np.vdot(a, b)来计算两个向量的点积。当两个向量均为一维向量时,vdot和dot没有区别。vdot和dot的区别主要有以下两点:
① 当np.vdot(a, b)的第一个参数为复数时,则使用a的共轭复数参与运算;
②当np.vdot(a, b)中的a, b为多维向量时,则将a,b都变为一维向量后运算。
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print np.dot(a, b)
print np.vdot(a, b)
c = np.array([1, 2, 3])
d = np.array([4, 5, 6])
print np.dot(c, d)
print np.vdot(c, d)
print np.dot([2j, 3j], [2j, 3j])
print np.vdot([2j, 3j], [2j, 3j])
输出:
[[19 22]
[43 50]]
70
32
32
(-13+0j)
(13+0j)
3、行列式的值
numpy.linalg.det()被用来求行列式的值。 对于 2×2 矩阵,它是左上和右下元素的乘积与其他两个的乘积的差。换句话说,对于矩阵[[a,b],[c,d]],行列式计算为ad-bc。
a = np.array([[1, 2], [3, 4]])
print a
print np.linalg.det(a)
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print b
print np.linalg.det(b)
输出:
[[1 2]
[3 4]]
-2.0000000000000004
[[1 2 3]
[4 5 6]
[7 8 9]]
-9.51619735392994e-16
4、矩阵的逆
使用numpy.linalg.inv()函数来计算矩阵的逆。 矩阵的逆是这样的,如果它乘以原始矩阵,则得到单位矩阵。
a = np.array([[1, 2], [3, 4]])
print a
b = np.linalg.inv(a)
print b
print np.dot(a, b)
输出:
[[1 2]
[3 4]]
[[-2. 1. ]
[ 1.5 -0.5]]
[[1.00000000e+00 1.11022302e-16]
[0.00000000e+00 1.00000000e+00]]
5、特征向量
可以使用np.linalg.eig(a)来求矩阵a的特征向量。
a = np.array([[1, 2], [3, 4]])
print a
eig1, eig2 = np.linalg.eig(a)
print eig2
输出:
[[1 2]
[3 4]]
[[-0.82456484 -0.41597356]
[ 0.56576746 -0.90937671]]
6、矩阵拼接
可以使用np.vstack((a, b))和np.hstack((a, b))来垂直拼接和水平拼接两个矩阵。
a = np.arange(9).reshape(3, 3)
b = np.arange(9).reshape(3, 3)
print a
print b
print np.vstack((a, b))
print np.hstack((a, b))
输出:
[[0 1 2]
[3 4 5]
[6 7 8]]
[[0 1 2]
[3 4 5]
[6 7 8]]
[[0 1 2]
[3 4 5]
[6 7 8]
[0 1 2]
[3 4 5]
[6 7 8]]
[[0 1 2 0 1 2]
[3 4 5 3 4 5]
[6 7 8 6 7 8]]
九、读取文件
1、使用np.genfromtxt()或者np.loadtxt()读取文件
在D盘根目录创建一个名为text.txt的文件,内容如下
可以使用np.genformtxt()读取文件
a = np.genfromtxt('D:\test.txt', delimiter=',')
print a
输出:
[[1. 2. 3.]
[4. 5. 6.]]
假如文件中有汉字的字段,则需要指定读取的类型dtype=np.str读取,将test.txt改为如下(utf8格式保存):
读取数据:
a = np.loadtxt('D:\test.txt',dtype=np.str, delimiter=',', encoding='utf8')
print a
a = a[:, 1:].astype(np.int) #使用切片得到要处理的数据并转换为int
print a
输出:
[['xefxbbxbfxe5xbcxa0xe4xb8x89' '1' '2' '3']
['xe6x9dx8exe5x9bx9b' '4' '5' '6']]
[[1 2 3]
[4 5 6]]
此外,使用结构数组也能读入这样的文件,并且可以使用不同的元素类型保存每个列的值:
persontype = np.dtype({ #自定义类型
'names':['name', 'age', 'weight', 'height'],
'formats':['S32','i', 'f', 'f']}) #指定每一列的类型
a = np.loadtxt('D:\test.txt',dtype=persontype, delimiter=',', encoding='utf8')
print a
输出:
[('xefxbbxbfxe5xbcxa0xe4xb8x89', 1, 2., 3.)
('xe6x9dx8exe5x9bx9b', 4, 5., 6.)]
2、使用np.savetxt()保存文件
a = np.arange(9).reshape(3, 3)
np.savetxt("D:output.txt", a) #浮点数保存,空格分隔
np.savetxt("D:output.txt", a, fmt='%d', delimiter=',') #整数保存,逗号分隔
十、参考
1、https://www.jianshu.com/p/83c8ef18a1e8
2、https://www.yiibai.com/numpy
3、https://www.cnblogs.com/laumians-notes/p/8288638.html