文章目录
NumPy数组
NumPy
(Numerical Python)是针对多维数组的一个科学计算包,支持高维数组与矩阵运算,提供了大量的数学函数库。但是要注意,数组内的元素必须是相同数据类型的。
对于深度学习来说,高维数组用的很多,因此要想学好深度学习,必须对NumPy了如指掌。(把之前发的那个修改了一下)
1.生成NumPy数组
首先要
import numpy as np
(1) 一般数组
np.array()
,传入任何序列对象都行,比如列表、元组、字符串等。
>>> arr = np.array([2,4,6,8])
>>> arr
array([2, 4, 6, 8])
>>> print(arr)
[2 4 6 8]
还可以生成多维数组,传入嵌套序列即可。例如生成二维数组:
>>> arr = np.array([[2,4],[6,8]])
>>> arr
array([[2, 4],
[6, 8]])
(2) 特殊类型数组
生成固定范围的随机数组1
np.arange(start,stop,step)
,生成一个以start
(默认为0)开始,stop
结束(不包括stop
),步长为step
(默认为1)的序列。
>>> np.arange(1,15,3)
array([ 1, 4, 7, 10, 13])
生成固定范围的随机数组2
np.linspace(start,end,num)
,生成一个以start
开始,以end
结尾,个数为num
的序列。
>>> np.linspace(0,100,10)
array([ 0. , 11.11111111, 22.22222222, 33.33333333,
44.44444444, 55.55555556, 66.66666667, 77.77777778,
88.88888889, 100. ])
它的前两个值和arange()
一样,代表开始值和终值,但有个区别是linspace()
默认包括终值。如果不想包括终值,加上endpoint = False
即可,对于第三个值它是指元素的个数,这个和arange
不一样,一定不要混淆。
生成指定形状全为0的数组
np.zeros()
>>> np.zeros(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
>>> np.zeros((3,4)) #生成3×4的矩阵
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
np.zeros_like(arr)
生成形状和arr一样且元素全是0的数组。
生成指定形状全为1的数组
np.ones()
,用法同上。
np.ones_like(arr)
,生成形状和arr一样且元素全是1的数组。
生成单位矩阵
np.eye(num)
,生成num
维单位矩阵。
>>> np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]]
(3) 生成随机数组
np.random.rand()
用于生成(0,1)
之间的随机数组。
当给rand()
传入一个具体值num
时,生成一个长度为num
的随机数组。
当给rand()
传入一对值时,生成相应行列的多维数组。
>>> np.random.rand()
0.43101195145330806
>>> np.random.rand(3)
array([0.27294823, 0.42849383, 0.41479483])
>>> np.random.rand(2,3)
array([[0.35974834, 0.39223821, 0.35084728],
[0.06587696, 0.41634962, 0.13933984]])
np.random.randn()
用来生成满足标准正态分布的指定形状数组。
对于传参同上。
>>> np.random.randn(3)
array([-0.15161607, 0.75490682, 0.76521087])
>>> np.random.randn(2,3)
array([[0.29118303, 2.03253717, 1.52058208],
[1.42187346, 0.35287314, 1.35656093]])
np.random.randint()
与arange()
方法类似,用于生成一定范围内的随机整数数组。
randint(low,high=None,size=None)
。当给size
传一个值生成的是一维数组,传一对值就是多维数组。
>>> np.random.randint(0,5,10)
array([1, 4, 4, 2, 2, 4, 2, 4, 1, 2])
>>> np.random.randint(5,size=(2,3))
array([[3, 1, 4],
[3, 1, 2]])
np.random.choice()
主要用于从已知数组中随机选取相应大小的数组。
choice(arr,size=None,replace=None)
,从数组arr
中选取大小为size
的数组作为一个新的数组。
arr
是整数时,从range(int)
中采用;是数组时,就从数组中取样。
size
的设置同上。
>>> np.random.choice(10,5)
array([9, 0, 4, 6, 7])
>>> np.random.choice(10,(2,3))
array([[3, 9, 8],
[6, 2, 3]])
np.random.shuffle()
将原数组顺序打乱。注意打乱的是原数组arr。
>>> arr = np.arange(10)
>>> arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.random.shuffle(arr)
>>> arr
array([4, 5, 8, 9, 3, 6, 0, 1, 7, 2])
2.NumPy数组的基本属性
(1) 数组的形状
shape
>>> arr = np.zeros((2,3))
>>> arr.shape
(2, 3)
(2) 数组的大小
size
,总共有多少个元素。
>>> arr = np.zeros((2,3))
>>> arr.size
6
(3) 数组的类型
dtype
>>> arr.dtype
dtype('float64')
数据类型主要有:
- int,整数
- float,浮点数
- bool,布尔类型
- object,Python对象类型
- string_,字符串类型,经常用S表示,S10表示长度为10的字符串
- unicode_,固定长度的unicode类型,跟字符串定义方式一样,常用U表示
(4) 数组的维数
ndim
>>> arr = np.zeros((2,3))
>>> arr.ndim
2
3.NumPy数组的数据选取
(1) 一维数组选取
像列表那样传索引获取:
>>> arr = np.arange(10)
>>> arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> arr[3]
3
>>> arr[-1]
9
>>> arr[1:-2]
array([1, 2, 3, 4, 5, 6, 7])
还可以传入某个判断条件,将返回符合该条件的元素
>>> arr[arr>3]
array([4, 5, 6, 7, 8, 9])
(2) 二维数组选取
获取行数据
也跟列表差不多(切片),只是每个元素变成了列表。
>>> arr = np.array([[2,4,6],[6,8,10],[1,3,5]])
>>> arr
array([[ 2, 4, 6],
[ 6, 8, 10],
[ 1, 3, 5]])
>>> arr[1]
array([ 6, 8, 10])
>>> arr[1:3]
array([[ 6, 8, 10],
[ 1, 3, 5]])
获取列数据
直接在列位置传入这个列的索引,例子如下:
>>> arr[:,2] #获取第三列
array([ 6, 10, 5])
>>> arr[:,[0,1]] #获取第1、2列
array([[2, 4],
[6, 8],
[1, 3]])
>>> arr[:,0:2] #获取第1、2列
array([[2, 4],
[6, 8],
[1, 3]])
行列同时获取
分别在行、列位置指明就行,例子如下:
>>> arr
array([[ 2, 4, 6],
[ 6, 8, 10],
[ 1, 3, 5]])
>>> arr[0:2,1:3] #获取第0、1行的 第1、2列
array([[ 4, 6],
[ 8, 10]])
(3) 三维数组选取
这也是最复杂的,在深度学习特征数据处理时用的是最多的。先来创建一个2行3列4通道
的数组,看看效果。
>>> np.ones((2,3,4))
array([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]])
这个三维数组有两块,第几块代表通道的第几行数据。
每一个块的每行数据代表通道的第几列数据。如此通道有3列数据。
每一列(上面的数组有4列)代表一个通道。
把最后一个元素改成0:
>>> arr = np.ones((2,3,4))
>>> arr[1,2,3] = 0
>>> arr
array([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 0.]]])
4.NumPy数组的数据预处理
(1) NumPy数组的类型转换
astype()
,传参数为np里的数据类型
>>> arr = np.array([True,True,False])
>>> arr.dtype
dtype('bool')
>>> arr.astype(np.int) #将arr转为int类型数组
array([1, 1, 0])
>>> arr_str = arr.astype(np.string_) #将arr转为str类型数组
>>> arr_str
array([b'True', b'True', b'False'], dtype='|S5')
>>> arr_str.dtype
dtype('S5')
(2) NumPy数组的缺失值处理
先判断是否含有缺失值(NumPy
中缺失值用np.nan
表示),有则将其找出来(用isnan()
,相应位置是缺失值则返回True
,否则返回False
);再对缺失值进行填充。
#创建一个有缺失值的数组
>>> arr = np.array([1,2,np.nan,4])
>>> arr
array([ 1., 2., nan, 4.]) #nan表示缺失值
>>> np.isnan(arr)
array([False, False, True, False]) #第三个为缺失值
>>> arr[np.isnan(arr)] = 0 #用0来填充缺失值(会对True的位置来填充)
>>> arr
array([1., 2., 0., 4.])
(3) NumPy数组的重复值处理
直接调用unique()方法可以去除重复值:
>>> arr = np.array([1,1,2,3,3])
>>> np.unique(arr)
array([1, 2, 3])
5.NumPy数组重塑
所谓重塑就是改变数组的形状,比如将3×4的变成4×3的数组。
(1) 一维数组重塑
将一维数组重塑为多行多列的数组,用reshape()
方法:
>>> arr = np.arange(8)
>>> arr
array([0, 1, 2, 3, 4, 5, 6, 7])
>>> arr.reshape(2,4) #重塑为2行4列数组
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
>>> arr.reshape(4,2)
array([[0, 1],
[2, 3],
[4, 5],
[6, 7]])
>>> arr.reshape(2,-1) #-1代表自动生成的意思
array([[0, 1, 2, 3],
[4, 5, 6, 7]])
>>> arr = np.arange(7)
>>> arr
array([0, 1, 2, 3, 4, 5, 6])
>>> arr.reshape(2,-1)
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
arr.reshape(2,-1)
ValueError: cannot reshape array of size 7 into shape (2,newaxis)
注意,要完成这个操作,元素个数必须要满足相应要求。
(2) 多维数组重塑
用法一样:
>>> arr = np.array([[2,4,6,8],[2,6,8,10],[1,3,5,7]])
>>> arr
array([[ 2, 4, 6, 8],
[ 2, 6, 8, 10],
[ 1, 3, 5, 7]])
>>> arr.reshape(2,6)
array([[ 2, 4, 6, 8, 2, 6],
[ 8, 10, 1, 3, 5, 7]])
>>> arr.reshape(4,3)
array([[ 2, 4, 6],
[ 8, 2, 6],
[ 8, 10, 1],
[ 3, 5, 7]])
(3) 数组转置
.T方法,n×m变m×n数组。
>>> arr = np.array([[2,4,6,8],[2,6,8,10],[1,3,5,7]])
>>> arr
array([[ 2, 4, 6, 8],
[ 2, 6, 8, 10],
[ 1, 3, 5, 7]])
>>> arr.T
array([[ 2, 2, 1],
[ 4, 6, 3],
[ 6, 8, 5],
[ 8, 10, 7]])
(4) 维度交换
先来看一个例子:
>>> a = np.arange(10).reshape(2,5)
>>> b = a.swapaxes(0,1)
>>> a
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> b
array([[0, 5],
[1, 6],
[2, 7],
[3, 8],
[4, 9]])
通过swapaxes()
将数组的第0轴和第1轴进行了交换,由2行5列变成了5列2行。再看三维数组的例子:
>>> a = np.arange(24).reshape(2,3,4)
>>> 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]]])
>>> b = a.swapaxes(0,1) #交换数组的第0轴和第1轴,变为(3,2,4)
>>> b
array([[[ 0, 1, 2, 3],
[12, 13, 14, 15]],
[[ 4, 5, 6, 7],
[16, 17, 18, 19]],
[[ 8, 9, 10, 11],
[20, 21, 22, 23]]])
解释:首先将第一块第一行的[0,1,2,3]的位置记为(1,1),第一块第二行的[4,5,6,7]的位置记为(1,2),第二块第三行的[20,21,22,23]记为(2,3),其它几个位置坐标类推。将第0轴和第1轴交换,所以第一块第一行的[0,1,2,3]的位置变为(1,1),还是第一块第一行;第一块第二行的[4,5,6,7]的位置变为(2,1),就是第二块第一行;第二块第三行的[20,21,22,23]变为(3,2),就是第三块第二行。
(4) 数组降维
通过reshape(-1)
、flatten()
和ravel()
函数将多维数组变成一维数组:
>>> a = np.arange(10).reshape(2,5)
>>> b = a.flatten() #flatten在英文中是“把...弄平”的意思
>>> c = a.reshape(-1)
>>> d = a.ravel()
>>> a
array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]])
>>> b
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> c
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> d
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
6.NumPy数组合并
(1) 横向合并
将两个行数相等的数组在行方向上进行简单拼接。
concatenate()
将待合并的数组以列表形式传给它,再通过设置axis=1
指明在行方向上合并。
>>> arr1 = np.array([[1,2,3],[4,5,6]])
>>> arr2 = np.array([[4,5,6,7],[7,8,9,0]])
>>> np.concatenate([arr1,arr2], axis=1)
array([[1, 2, 3, 4, 5, 6, 7],
[4, 5, 6, 7, 8, 9, 0]])
hstack()
将待合并的数组以元组形式传给它即可。
>>> np.hstack((arr1,arr2))
array([[1, 2, 3, 4, 5, 6, 7],
[4, 5, 6, 7, 8, 9, 0]])
column_stack()
将待合并的数组以元组形式传给它即可。
>>> np.column_stack((arr1,arr2))
array([[1, 2, 3, 4, 5, 6, 7],
[4, 5, 6, 7, 8, 9, 0]])
(2) 纵向合并
将两个列数相等的数组在行方向上进行简单拼接。用法与横向合并类似。
concatenate()
只需要让axis=0
即可。
vstack()
row_stack()
>>> arr1 = np.array([[1,2,3],[4,5,6]])
>>> arr2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> np.concatenate([arr1,arr2] ,axis=0)
array([[1, 2, 3],
[4, 5, 6],
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> np.vstack((arr1,arr2))
array([[1, 2, 3],
[4, 5, 6],
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> np.row_stack((arr1,arr2))
array([[1, 2, 3],
[4, 5, 6],
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
注意:当只有行数或列数不同时,可以不设置axis
参数,会自动按可以合并的方向合并。
7. 常用函数
(1) 元素级函数
函数 | 说明 |
---|---|
abs | 求各个元素的绝对值 |
sqrt | 求各个元素的平方根 |
square | 求各个元素的平方 |
exp | 计算各个元素的以e为底的指数,e^x |
log、log10、log2、log1p | 分别计算以e为底、10为底、2为底的对数,以及log(1+x) |
modf | 适用于浮点数,将小数和整数部分以独立的数组返回 |
isnan | 用来判断是否是NaN,返回布尔值 |
>>> arr1 = np.array([[1,2,3],[4,5,6]])
>>> np.square(arr1)
array([[ 1, 4, 9],
[16, 25, 36]], dtype=int32)
(2) 描述统计函数
对整个NumPy数组或某条轴的数据进行统计运算,主要函数:
函数 | 说明 |
---|---|
sum | 对数组中的全部元素或某行/列的元素求和 |
mean | 平均值求取 |
std | 标准差 |
var | 方差 |
min、max | 最大值、最小值 |
argmax、argmin | 返回最大值、最小值的对应索引 |
cumsum | 所有元素累计和,结果以数组形式返回 |
sumprod | 所有元素的累计积 |
通过设置axis
参数选择对行/列,或所有元素进行统计。
>>> arr1 = np.array([[1,2,3],[4,5,6]])
>>> arr1.sum()
21
>>> arr1.sum(axis=1) #对数组中每一行分别求和
array([ 6, 15])
>>> arr1.sum(axis=0) #对数组中每一列分别求和
array([5, 7, 9])
(3) 条件函数
np.where(condition, x, y)
,如果condition
(条件)为真返回x,否则返回y。
>>> arr = np.array([50,60,70,50])
>>> np.where(arr==50,'等于50','不等于50')
array(['等于50', '不等于50', '不等于50', '等于50'], dtype='<U5')
>>> np.where(arr>=60) #返回满足条件的值的索引
(array([1, 2], dtype=int64),)
(4) 集合关系
每个数组可以粗略当作一个集合(当然集合不该有重复元素~),可以进行集合关系的运算,主要有包含、交集、并集、差集。
>>> arr1 = np.array([1,2,3,4])
>>> arr2 = np.array([1,2,5])
#判断数组arr1中包含数组arr2中的哪些值,如果包含则对应位置返回True,否则返回False。
>>> np.in1d(arr1,arr2)
array([ True, True, False, False])
#返回两个数组的交集
>>> np.intersect1d(arr1,arr2)
array([1, 2])
#返回两个数组的并集
>>> np.union1d(arr1,arr2)
array([1, 2, 3, 4, 5])
#返回两个数组的差集
>>> np.setdiff1d(arr1,arr2)
array([3, 4])
(3) 条件函数
np.where(condition, x, y)
,如果condition
(条件)为真返回x,否则返回y。
>>> arr = np.array([50,60,70,50])
>>> np.where(arr==50,'等于50','不等于50')
array(['等于50', '不等于50', '不等于50', '等于50'], dtype='<U5')
>>> np.where(arr>=60) #返回满足条件的值的索引
(array([1, 2], dtype=int64),)
(4) 集合关系
每个数组可以粗略当作一个集合(当然集合不该有重复元素~),可以进行集合关系的运算,主要有包含、交集、并集、差集。
>>> arr1 = np.array([1,2,3,4])
>>> arr2 = np.array([1,2,5])
#判断数组arr1中包含数组arr2中的哪些值,如果包含则对应位置返回True,否则返回False。
>>> np.in1d(arr1,arr2)
array([ True, True, False, False])
#返回两个数组的交集
>>> np.intersect1d(arr1,arr2)
array([1, 2])
#返回两个数组的并集
>>> np.union1d(arr1,arr2)
array([1, 2, 3, 4, 5])
#返回两个数组的差集
>>> np.setdiff1d(arr1,arr2)
array([3, 4])
上面就是我对NumPy在深度学习中最常见的几点的介绍,其实还有许多,平时还是要多多搜索与积累。