numpy概述
numpy是一个很强大的针对数组、矩阵的科学计算库,由于机器学习大量需要进行矩阵运算,而图像的本质也是数值矩阵,因此在机器学习、图像处理应用非常频繁。这里总结一下numpy的一些常用操作。
数组类型Ndarray
- 创建数组类型Ndarray
ndarray对象是用于存放同类型元素的多维数组,是numpy中的基本对象之一。我们通常可以用numpy.array的方式创建一个ndarray的数组。
>>> pytuple = (4,5,6)
>>> ll = np.array(pytuple)
>>> ll
array([4, 5, 6])
可以通过元组tuple构建array:
>>> pytuple = (4,5,6)
>>> ll = np.array(pytuple)
>>> ll
array([4, 5, 6])
通过list构建array
>>> pylist = [0,1,2]
>>> jj = np.array(pylist)
>>> jj
array([0, 1, 2])
构建多维的array
>>> pylist1 = [1,2,3]
>>> pylist2 = [4,5,6]
>>> marray = np.array([pylist1,pylist2])
>>> marray
array([[1, 2, 3],
[4, 5, 6]])
- Ndarray对象常用属性
ndarray对象最常用属性包括:
属性 | 含义 |
---|---|
T | 转置,与self.transpose( )相同,如果维度小于2返回self |
size | 数组中元素个数 |
itemsize | 数组中单个元素的字节长度 |
dtype | 数组元素的数据类型对象 |
ndim | 数组的维度 |
shape | 数组的形状 |
data | 指向存放数组数据的python buffer对象 |
flat | 返回数组的一维迭代器 |
nbytes | 数组中所有元素的字节长度 |
示例如下: 针对marry数组,我们可以查看:
>>> pylist1 = [1,2,3]
>>> pylist2 = [4,5,6]
>>> marray = np.array([pylist1,pylist2])
>>> marray.T
array([[1, 4],
[2, 5],
[3, 6]])
>>> marray.size
6
>>> marray.itemsize
8
>>> marray.dtype
dtype('int64')
>>> marray.ndim
2
>>> marray.shape
(2, 3)
>>> marray.data
<memory at 0x11ecaf558>
>>> for item in marray.flat:
>>> print(item)
1
2
3
4
5
6
>>> marray.nbytes
48
- 数组类型
在创建数组时,可以根据初始值自动推断数组的数值类型
>>> a = np.array([1,2,3.5])
>>> a
array([1. , 2. , 3.5])
>>> c = np.array(['1',2,3])
>>> c
array(['1', '2', '3'], dtype='<U1')
或者明确指定数组类型:
>>> a = np.array([1,2,3.5], dtype=np.float32)
>>> a
array([1. , 2. , 3.5])
>>> c = np.array(['1',2,3] ,dtype=np.ubyte)
>>> c
array(['1', '2', '3'])
常用数组快速创建方法
- 一维序列数组
可以通过np.arange(),类似于python原生的range,通过指定开始值,终值和步长来创建表示等差数列的一维数组。
注意该函数和range一样结果不包含终值。np.arange(start,end,step)
>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(0,1,0.1)
array([ 0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
>>> np.arange(10,0,-1)
array([10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
- 等差数列
np.linspace()函数可以生成一个等差数列,与上面np.arange不同的是,该函数第三个参数指定的是元素个数,它表示给定起始值和终点值以及元素个数,生成一个一维的等差数列。
含有参数endpoint布尔值,默认为True表示包含终值,设定为False表示不包含终值。np.linspace(start,end,count,endpoint=True)
示例代码如下:
>>> a=np.linspace(0,1,10)
>>> print(a)
[0. 0.11111111 0.22222222 0.33333333 0.44444444 0.55555556
0.66666667 0.77777778 0.88888889 1. ]
>>> b=np.linspace(0,1,10,endpoint = False)
>>> print(b)
[0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
- 等比数列
np.logspace()用于生成等比数列。该函数与np.linspace类似,不过它起始值是base的start次方,结束值是base的end次方,base基数默认为10。
np.logspace(start,end,count,base=10)
>>> np.logspace(0,3,4)
array([ 1., 10., 100., 1000.])
>>> np.logspace(0,3,4,base=2)
array([ 1., 2., 4., 8.])
- 全0数组
np.zeros()函数用于生成值全为0的数组。至少要传入一个参数表示数组形状。
>>> np.zeros(5)
array([ 0., 0., 0., 0., 0.])
>>> np.zeros((3,5))
array([[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0.]])
- 全1数组
np.ones()函数用于生成值全为1的数组。至少要传入一个参数表示数组形状。
>>> np.ones(5)
array([ 1., 1., 1., 1., 1.])
>>> np.ones((3,5))
array([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.]])
- 全x数组
np.full()函数可以生成初始化为指定值的数组。至少要传入两个个参数。一个为数组的shape,一个为初始化的值。
np.full(shape,init_data)
>>> np.full(5, -1)
array([-1, -1, -1, -1, -1])
>>> np.full((2,3),5)
array([[5, 5, 5],
[5, 5, 5]])
数组维度变换与重塑
reshape函数将数组对象的shape进行重塑。
新数组的shape属性应该要与原来数组的一致,即新数组元素数量与原数组元素数量要相等。
>>> a =np.array([[ 1, 2, 3,4],
[ 5, 6, 7,8],
[ 9, 10, 11,12]])
>>> b = a.reshape(6,2)
>>> b
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12]])
当reshape一个参数为-1时,那么reshape函数会根据另一个参数的维度计算出数组的另外一个shape属性值。
>>> a =np.array([[ 1, 2, 3,4],
[ 5, 6, 7,8],
[ 9, 10,11,12]])
>>> b = a.reshape(-1,2)
>>> b
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10],
[11, 12]])
resize和reshape功能类似,reshape是返回新数组,而resize可以直接修改原始数组
>>> c =np.array([[ 1, 2, 3,4],
[ 5, 6, 7,8],
[ 9, 10,11,12]])
>>> c.resize(2,6)
>>> c
array([[ 1, 2,3, 4,5, 6],
[ 7, 8,9,10,11,12]])
数组索引与切片方法
- 数组索引
与Python中定义的序列类似,NumPy支持同样的方法对数组进行索引。
>>> a =np.array([[ 1, 2, 3,4],
[ 5, 6, 7,8],
[ 9, 10, 11,12]])
>>> a[2][3]
12
>>> a[0][1]
2
●注意:Python的索引是从0开始。
这种数据索引方式在numpy中不推荐,一般我们使用:
>>> a[2, 3]
12
>>> a[0, 1]
2
- 数组切片
数组通过指定索引的范围,来实现切片。
如a[2:5],是指一维索引从2开始,到5结束,但不包括5在内。
>>> a =np.array([ 1, 2, 3,4,5, 6, 7,8])
>>> a[1:5]
array([2, 3, 4, 5])
>>> a[3:5]
array([4, 5])
>>> a =np.array([[ 1, 2, 3,4], [ 5, 6, 7,8], [ 9, 10, 11,12]])
>>> a[1:2]
array([[5, 6, 7, 8]])
>>> a[1:3]
array([[ 5, 6, 7, 8], [ 9, 10, 11, 12]])
数组切片可以缺省索引值。
如a[:5],是指一维索引从缺省的0开始,到5结束,但不包括5在内。
如a[2:],是指一维索引从2开始,到缺省的最后值为止,包括最后值。
>>> a =np.array([ 1, 2, 3,4,5, 6, 7,8])
>>> a[:5]
array([1,2, 3, 4, 5])
>>> a[3:]
array([4, 5, 6, 7, 8])
>>> a =np.array([[ 1, 2, 3,4], [ 5, 6, 7,8],[ 9, 10, 11,12]])
>>> a[1:]
array([[5, 6, 7, 8], [ 9, 10, 11,12]])
>>> a[:]
array([[ 1, 2, 3,4],[ 5, 6, 7,8],[ 9, 10, 11,12]])
数组切片可以使用“-”号进行索引。
如 a[-1],是指一维索引取最后一个值。
如 a[:-1],是指一维索引从缺省的0开始,到最后一个值结束,但不包括最后一个值在内。
>>> a =np.array([[ 1, 2, 3,4], [ 5, 6, 7,8], [ 9, 10, 11,12]])
>>> a[-1]
array([ 9, 10, 11,12])
>>> a[-1,-1]
12
>>> a[:-1]
array([[1, 2, 3,4],[5, 6, 7, 8]])
>>> a[:-1,:-2]
array([[1, 2], [5, 6]])
- 迭代切片
Numpy array可以通过“::”对数组进行迭代提取数值。
如 a[1:10:2],表示从数值索引“1”开始,到索引“10”为止(但不包括“10”),没间隔2个提取一个值。
当最后一个间隔值变成-1时,则代表对数组进行翻转。
>>> a =np.array([ 1, 2, 3,4,5, 6, 7,8])
>>> a[::3]
array([1, 4, 7])
>>> a[:6:2]
array([1, 3, 5])
>>> a[3::2]
array([4, 6, 8])
>>> b =np.array([[ 1, 2, 3,4], [ 5, 6, 7,8], [ 9, 10, 11,12]])
>>> b[::-1]
array([[ 9, 10, 11, 12], [ 5, 6, 7, 8], [ 1, 2, 3, 4]])
- 数组迭代器
Array 的 flat属性可以将多维数组变成一个迭代器。便于对数组中每个原始进行计算。
如 a.flat 返回类型为numpy.flatiter,数组a的迭代器。
>>> a =np.array([[ 1, 2, 3,4], [ 5, 6, 7,8], [ 9, 10, 11,12]])
>>> for i in a:
print (i)
[1 2 3 4]
[5 6 7 8]
[ 9 10 11 12]
>>> a.flat
<numpy.flatiter at 0x380f800>
>>> for i in a.flat:
print (i)
1 2 3 4 5 6 7 8 9 10 11 12
数组的文件存取
NumPy可以用专有的二进制类型保存数据,文件后缀为npy。通过np.load和np.save这两个函数可以方便的读写数组文件,自动处理元素类型和shape等信息。
>>> import numpy as np
>>> a =np.array([[ 1, 2, 3, 4], [ 5, 6, 7, 8], [ 9, 10, 11,12]],dtype=np.float32)
>>> np.save("a.npy",a)
>>> new_a = np.load("a.npy")
>>> new_a
array([[ 1., 2., 3., 4.],
[ 5., 6., 7., 8.],
[ 9., 10., 11., 12.]], dtype=float32)
random方法
randint
>>> np.random.randint(0, 10) # [0, 10)之间的随机数
5
>>> np.random.randint(0, 10, 10)
array([2, 6, 1, 8, 1, 6, 8, 0, 1, 4])
>>> np.random.randint(0, 1, 10)
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
>>> np.random.randint(0, 10, size=10)
array([3, 4, 9, 9, 5, 2, 3, 3, 2, 1])
>>> np.random.randint(0, 10, size=(3,5))
array([[1, 5, 3, 8, 5],
[2, 7, 9, 6, 0],
[0, 9, 9, 9, 7]])
>>> np.random.randint(1, size=(3,5))
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
seed
>>> np.random.seed(666)
... np.random.randint(0, 10, size=(3, 5))
array([[2, 6, 9, 4, 3],
[1, 0, 8, 7, 5],
[2, 5, 5, 4, 8]])
# 指定某个seed,重复生成的ndarray是一致的
random
np.random.random((1000, 20))
# 上面这个就代表生成1000行 20列的浮点数,浮点数都是从[0,1)中随机。
normal
>>> np.random.normal() # 默认生成一个服从均值为0,标准差为1的正态分布的随机数
>>> np.random.normal(0, 1, (3, 5))
array([[ 0.82101369, 0.36712592, 1.65399586, 0.13946473, -1.21715355],
[-0.99494737, -1.56448586, -1.62879004, 1.23174866, -0.91360034],
[-0.27084407, 1.42024914, -0.98226439, 0.80976498, 1.85205227]])