人工智能00005 深度学习与图像识别书评05 图像识别前置技术02 Numpy数组02

2.3.2 创建Numpy数组

可以通过创建Python列表(list)的方式来创建Numpy矩阵,

比如输入

nparray=np.array([i for i in range(10)]),

可以看到返回的结果是array([0,1,2,3,4,5,6,7,8,9])。

同样,也可以通过Python列表的方式来修改值,比如输入nparray[0]=10,再来观察nparray的向量内容就会发现返回的结果是array([10,1,2,3,4,5,6,7,8,9])。

Numpy数组还封装了其他方法来创建矩阵。首先,我们介绍第一个方法np.zeros(从命名规则来看,这个方法就是用来创建数值都为0的向量),比如,我们输入: a = np.zeros(10) 可以看到结果为: array([ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]) 从上述结果可以看出,每一个0后面都有一个小数点,

调用a.dtype会发现我们创建的这个向量的类型为dtype(‘float64’)。

值得注意的是:在大部分图像识别算法开发中,我们使用的都是float64这个类型。如果希望在创建Numpy矩阵的时候强制规定一种类型,那么我们可以使用以下代码:

np.zeros(10,dtype=int) 这样,返回的结果在矩阵中的数据就都是整型0了。

介绍完使用zeros方法创建向量之后,再来看看如何创建一个 多维矩阵。

我们可以使用传入元组的方式,代码如下: np.zeros(shape=(3,4)) #代表创建的是三行四列的矩阵并且其数据类型为float64

返回的结果为:

array([[ 0., 0., 0., 0.],

[ 0., 0., 0., 0.],

[ 0., 0., 0., 0.]])

与np.zeros方法相似的还有np.ones方法,顾名思义,np.ones方法创建的矩阵的数值 都为1。

举个例子: np.ones((3,4)) 返回的结果如下: array([[ 1., 1., 1., 1.],

[ 1., 1., 1., 1.],

[ 1., 1., 1., 1.]])

读者可能会比较好奇,既然我们可以创建数值全为0的矩阵,也可以创建数值全为1的矩阵,那么Numpy是否提供了一个方法可以让我们自己指定值呢?答案是肯定的,这

个方法就是np.full方法,我们来看一个例子,代码如下: np.full((3,5),121) #这个方法的意思是我们创建了一个三行五列的矩阵,默认值为121 返回的结果是:

array([[121, 121, 121, 121, 121],

[121, 121, 121, 121, 121],

[121, 121, 121, 121, 121]])

我们也可以使用np.arange方法来创建Numpy的矩阵。

示例代码如下:

np.arange(0,20,2)#arange接收三个参数,与Python中的range方法相似,arange也是前闭后开的方法,第一个参数为向量的第一个值0,第二个参数为最后一个值20,因为是后开所以取的是18,第三个参数为步长,默认为1,本例中设置为2,所以最后一个值是18。

返回的结果是: array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])

我们可以使用np.linspace方法(前闭后闭)来对Numpy矩阵进行等分,比如将0~10等分为5份的代码如下: np.linspace(0,10,5) 返回的结果是: array([ 0. , 2.5, 5. , 7.5, 10. ]) 下面通过几个例子再来看看在Numpy矩阵中如何生成随机数矩阵。

1)生成一个长度为10的向量,里面每一个数值都是介 于0~10之间的整数,代码如下: import numpy as np

np.random.randint(0,10,10)

2)如果不确定每个参数代表的意思,则加上参数名size,代码如下: np.random.randint(0,5,size=5) #注意是前闭后开,永远取不到5

3)我们也可以生成一个三行五列的整数矩阵,代码如下 np.random.randint(4,9,size=(3,5))

4)seed的作用:如果不希望每次生成的随机数都不固定,那么我们可以使用np.random.seed(1),随机种子使用数字1记录,这以后只要是用随机种子1生成的随机数就都是固定的。

5)我们也可以生成介于0~1之间的浮点数的向量或者矩阵,代码如下: np.random.random(10) #生成0~1之间的浮点数,向量的长度为10

np.random.random((2,4)) #生成0~1之间的浮点数,二行四列的矩阵

6)np.random.normal()表示的是一个正态分布,normal在这里是正态的意思。

numpy.random.normal(loc=0,scale=1,size=shape)的意义如下。 ·参数loc(float):正态分布的均值,对应这个分布的中 心。loc=0说明这是一个以Y轴为对称轴的正态分布。

·参数scale(float):正态分布的标准差,对应分布的宽度,scale越大,正态分布的曲线越矮胖,scale越小,曲线越高瘦。

·参数size(int或者整数元组):输出的值赋在shape里,默认为None。


2.3.3 获取Numpy属性


首先,我们通过Numpy中的一个方法arange(n),生成0到n-1的数组。

比如,我们输入np.arange(15),可以看到返回的结果是array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14])。 然后,再通过Numpy中的reshape(row,column)方法,自动构架一个多行多列的array对象。 比如,我们输入:


a = np.arange(15).reshape(3,5) #代表3行5列 可以看到结果: array([[ 0, 1, 2, 3, 4],

[ 5, 6, 7, 8, 9],

[10, 11, 12, 13, 14]]) 有了基本数据之后,我们就可以通过Numpy提供的shape属性获取Numpy数组的行数与列数,

示例代码如下: print(a.shape)

可以看到返回的结果是一个元组(tuple),第一个3代表的是3行,第二个5代表的是5列: (3, 5)

轮到你来: 使用arange和reshape方法自定义一个Numpy数组,最后通过Python中的print方法打印出数组的shape值(返回的应该是一个元组类型)。

我们可以通过.ndim来获取Numpy数组的维度,示例 代码如下:

importnumpy as np

x = np.arange(15)

print(x.ndim) #输出x向量的维度,这时能看到的维度是1维

X = x.reshape(3,5) #将x向量转为三行五列的二维矩阵

Print(X.ndim) #输出X矩阵的维度,这时能看到的维度是2维reshape方法的特别用法 如果只关心需要多少行或者多少列,其他由计算机自己 来算,

那么这个时候我们可以使用如下方法: x.reshape(15,-1) #我关心的是我只要15行,列由计算机自己来算

x.reshape(-1,15) #我关心的是我只要15列,行由计算机自己来算


2.3.4 Numpy数组索引

Numpy支持类似list的定位操作,示例代码如下:

import numpy as np

matrix = np.array([[1,2,3],[20,30,40]])

print(matrix[0,1]) 得到的结果是2。


上述代码中的matrix[0,1],0代表的是行,在Numpy中,0代表起始的第一个,所以取的是第1行,之后的1代表 的是列,所以取的是第2列。

那么,最后的输出结果是取第一行第二列,也就是2这个值了。

2.3.5 切片

Numpy支持类似list的切片操作,示例代码如下: import numpy as np

matrix = np.array([

[5, 10, 15],

[20, 25, 30],

[35, 40, 45]

])

print(matrix[:,1])

print(matrix[:,0:2])

print(matrix[1:3,:])

print(matrix[1:3,0:2])


上述的

print(matrix[:,1])语法代表选择所有的行,而且列的索引是1的数据,因此返回的结果是10,25,40。

print(matrix[:,0:2])代表的是选取所有的行,而且列的索引是0和1的数据。

print(matrix[1:3,:])代表的是选取所有的列,而且行的索引值是1和2的数据。

print(matrix[1:3,0:2])代表的是选取行的索引是1和2,而且列的索引是0和1的所有数据。

2.3.6 Numpy中的矩阵运算

矩阵运算(加、减、乘、除),将严格按照数学公式来进行演示,即两个矩阵的基本运算必须具有相同的行数与列数。本例只演示两个矩阵相减的操作,其他的操作读者可以自行测试。

示例代码如下:

import numpy as np

myones = np.ones([3,3])

myeye = np.eye(3)

#生成一个对角线的值为1,其余值都 为0的三行三列矩阵

print(myeye)

print(myones-myeye) 输出结果如下:

[[ 1. 0. 0.]

[ 0. 1. 0.]

[ 0. 0. 1.]]

[[ 0. 1. 1.]

[ 1. 0. 1.]

[ 1. 1. 0.]]

提示numpy.eye(N,M=None,k=0, dtype=)中第一个参数输出矩阵(行数=列数),第三个参数默认情况下输出的是对角线的值全为1,其余值全为0。

除此之外,Numpy还预置了很多函数,使用这些函数可以作用于矩阵中的每个元素。

Numpy预置函数及说明

(1)矩阵之间的点乘 矩阵真正的乘法必须满足 第一个矩阵的列数等于第二个矩阵的行数,

矩阵乘法的函数为dot。示例代码如下: import numpy as np

mymatrix = np.array([[1,2,3],[4,5,6]])

a = np.array([[1,2],[3,4],[5,6]])

print(mymatrix.shape[1] == a.shape[0])

print(mymatrix.dot(a)) 其输出结果如下: [[22 28]

[49 64]]

上述示例代码的原理是将mymatrix的第一行[1,2,3]与a矩阵的第一列[1,3,5]相乘然后相加,接着将mymatrix的第一行[1,2,3]与a矩阵的第二列[2,4,6]相乘然后相加,以此类推。

(2)矩阵的转置 矩阵的转置是指将原来矩阵中的行变为列。示例代码如下: import numpy as np

a = np.array([[1,2,3],[4,5,6]]) print(a.T) 输出结果如下: [[1 4]

[2 5]

[3 6]]

(3)矩阵的逆 需要首先导入numpy.linalg,再用linalg的inv函数来求逆,矩阵求逆的条件是矩阵的行数和列数必须是相同的。示例代码如下: import numpy as np

import numpy.linalg as lg

A = np.array([[0,1],[2,3]])

invA = lg.inv(A)

print(invA)

print(A.dot(invA)) 输出结果如下: [[-1.5 0.5]

[ 1. 0. ]] 逆矩阵就是,原矩阵A.dot(invA)以及逆矩阵invA.dot(A)的结果都为单位矩阵。并不是所有的矩阵都有逆矩阵。


2.3.7 数据类型转换


Numpy ndarray数据类型可以通过参数dtype进行设定,而且还可以使用参数astype来转换类型,在处理文件时该参数会很实用。

注意,astype调用会返回一个新的数组,也就是原始数据的备份。

比如,将String转换成float。示例代码如下: vector = numpy.array(["1", "2", "3"])

vector = vector.astype(float) 注意在上述例子中,如果字符串中包含非数字类型,那么从string转换成float就会报错。

2.3.8 Numpy的统计计算方法

NumPy内置了很多计算方法,其中最重要的统计方法及说明具体如下。

·sum():计算矩阵元素的和;矩阵的计算结果为一个一维数组,需要指定行或者列。

·mean():计算矩阵元素的平均值;矩阵的计算结果为一个一维数组,需要指定行或者列。

·max():计算矩阵元素的最大值;矩阵的计算结果为一 个一维数组,需要指定行或者列。

·mean():计算矩阵元素的平均值。

·median():计算矩阵元素的中位数。 需要注意的是,用于这些统计方法的数值类型必须是int或者float。

数组示例代码如下: vector = numpy.array([5, 10, 15, 20])

vector.sum() 得到的结果是50 矩阵示例代码如下:

matrix=

array([[ 5, 10, 15],

[20, 10, 30],

[35, 40, 45]])

matrix.sum(axis=1)

array([ 30, 60, 120])

matrix.sum(axis=0)

array([60, 60, 90]) 如上述例子所示,axis=1计算的是行的和,结果以列的形式展示。axis=0计算的是列 的和,结果以行的形式展示。

延伸学习: 官方推荐教程(https://docs.scipy.org/doc/numpy-dev/user/quickstart.html)是不错的入门选择。

2.3.9 Numpy中的arg运算

argmax函数就是用来求一个array中最大值的下标。

简单来说,就是最大的数所对应的索引(位置)是多少。

示例代码如下: index2 = np.argmax([1,2,6,3,2])    #返回的是2 argmin函数可用于求一个array中最小值的下标,用法与argmax类似。

示例代码如下: index2 = np.argmin([1,2,6,3,2]) # 返回的是0 下面我们来探索下Numpy矩阵的排序和如何使用索引,

示例代码如下: import numpy as np

x = np.arange(15)

print(x)  # array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])

np.random.shuffle(x)  #随机打乱

print(x)  # array([ 8, 13, 12, 3, 9, 2, 10, 0, 11, 5, 14, 7, 1, 4, 6])

sx = np.argsort(x)  #从小到大 排序,返回索引值

print(sx)  # [ 7 12 5 3 13 9 14 11 0 4 6 8 2 1 10]

这里简单解释一下,第一个元素7代表的是x向量中的0的索引地址,第二个元素12代表的是x向量中的1的索引地址,其他元素以此类推。


2.3.10 FancyIndexing

要索引向量中的一个值是比较容易的,比如通过x[0]来取值。

但是,如果想要更复杂地取数,比如,需要返回第3个、第5个以及第8个元素时,应该怎么办?示例代码如下:

import numpy as np

x = np.arange(15)

ind = [3,5,8]

print(x[ind]) #使用fancyindexing就可以解决这个问题 我们也可以从一维向量中构成新的二维矩阵,示例代码如下:

import numpy as np

x = np.arange(15)

np.random.shuffle(x)

ind = np.array([[0,2],[1,3]]) #第一行需要取x向量中索引为0的元素,以及索引为2的元素,

         第二行需要取x向量中索引为1的元素以及索引为3的元素

print(x) print(x[ind]) 我们来看下输出结果很容易就能明白了:

[ 3 2 7 12 9 13 11 14 10 5 4 1 6 8 0]

[[ 3 7]

[ 2 12]] 对于二维矩阵,我们使用fancyindexing取数也是比较容易的,示例代码如下:

import numpy as np

x = np.arange(16) X = x.reshape(4,-1)

row = np.array([0,1,2])

col = np.array([1,2,3])

print(X[row,col])    #相当于取三个点,分别是(0,1),(1,2),(2,3)

print(X[1:3,col])    #相当于取第2、3行,以及需要的列 2.3.11 Numpy数组比较 Numpy有一个强大的功能是数组或矩阵的比较,数据比较之后会产生boolean值。

示例代码如下:

import numpy as np

matrix = np.array([

[5, 10, 15],

[20, 25, 30],

[35, 40, 45]

])

m = (matrix == 25)

print(m) 我们看到输出的结果如下: [[False False False]

[False True False]

[False False False]] 下面再来看一个比较复杂的例子,示例代码如下: import numpy as np

matrix = np.array([

[5, 10, 15],

[20, 25, 30],

[35, 40, 45]

]) second_column_25 = (matrix[:,1] == 25)

print(second_column_25)

print(matrix[second_column_25, :]) 上述代码中,print(second_column_25)输出的是[False,True False],首先matrix[:,1]代表的是所有的行,以及索引为1的列,即[10,25,40],最后与25进行比较,得到的就是[False,True,False]。

print(matrix[sec ond_column_25,:])代表的是返回true值的那一行数据,即[20,25,30]。 注意上述的示例是单个条件,Numpy也允许我们使用条件符来拼接多个条件,其中“&”代表的是“且”,“|”代表的是“或”。

比如,vector=np.array([5,10,11,12]),equal_to_five_and_ten=(vector==5)&(vector==10)返回的都是false,如果是equal_to_five_or_ten=(vector==5)|(vector==10),则返回 的是[True,True,False,False]。

比较之后,我们就可以通过np.count_nonzero(x<=3)来计算小于等于3的元素个数了,1代表True,0代表False。也可以通过np.any(x==0),只要x中有一个元素等于0就返回True。np.all(x>0)则需要所有的元素都大于0才返回True。

这一点可以帮助我们判断x里的数据是否满足一定的条件。


小结 工欲善其事,必先利其器。

介绍了让图像识别工作变得更高效的一些“利器”,如使用Anaconda快速构建开发环境,以及如何使用Numpy进行科学计算等。

应重点关注Numpy,因为在一些具体任务上,在开始时通常都需要将图片存储于Numpy矩阵中以进行相应的计算,比如后续章节讲到的KNN算法,就需要通过Numpy的科学运算来计算 每张测试样本图与训练图之间的距离。

此外,由于篇幅限制,无法逐一对诸如Pandas、Matplotlib等常用的Python库进行介绍,希望读者自行查找相关资料。另外,还有一点值得注意的是,在入门图像识别之前,读者需有一定的Python基础。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容