ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

第3关 苦练基本功(下)_numpy - 小象学院

2021-03-17 09:31:57  阅读:221  来源: 互联网

标签:矩阵 print 苦练 arr2 数组 np 基本功 numpy


课程目录 小象学院 - 人工智能

关注公众号【Python家庭】领取1024G整套教材、交流群学习、商务合作。整理分享了数套四位数培训机构的教材,现免费分享交流学习,并提供解答、交流群

你要的白嫖教程,这里可能都有喔~

 

恭喜你闯进了第3关,让我们继续探索人工智能的奥秘,体验算法的魔力Amazing~

    本关我们将学习更高阶的基本功,进一步提高我们的动手能力,为后面的“大战”做准备。   先做个热身运动,使用上一关学习的数组相关操作,先创建两个数组。     AI_3_0_1
import numpy as np

# 创建一个3行6列的二维全1数组,元素类型是整型int
arr1 = np.ones((3,6), dtype=int)

# 创建一个包含6个0的一维数组,元素类型是整型int
arr2 = np.zeros(6, dtype=int)

# 打印数组的基本信息

print("arr1是一个{}维数组".format(arr1.ndim))
print("arr1包含{}个元素".format(arr1.size))
print("arr1的形状:{}行,{} 列".format(arr1.shape[0],arr1.shape[1]))
print(arr1)

print("arr2是一个{}维数组".format(arr2.ndim))
print("arr2包含{}个元素".format(arr2.size))
print(arr2)

 

合并数组

 

沿垂直方向合并

 

需求1:在垂直方向上合并arr1和arr2

 

关于数组合并的问题,numpy提供了专门的函数解决,在垂直方向上合并数组可以使用vstack函数实现,在水平方向上合并数组可以使用hstack函数实现。

 

AI_3_0_2

import numpy as np

# 创建一个3行6列的二维全1数组,元素类型是整型int
arr1 = np.ones((3,6), dtype=int)

# 创建一个包含6个0的一维数组,元素类型是整型int
arr2 = np.zeros(6, dtype=int)

np.vstack((arr1,arr2))
array([[1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 0, 0]])

使用vstack函数在垂直方向上合并两个数组需要注意:两个数组每行的元素个数要相同,也就是每行的列数要相同。否则两个数组在垂直方向上没法拼接在一起。

  我们已经注意到,虽然arr1和arr2两个数组的形状不同,但是vstack可以自动根据数组的特点把它们合并在一起。   通过vstack合并完之后,通过打印原数组arr1和arr2,看看这两个数组是不是发生了改变。     AI_3_0_3  
import numpy as np

# 创建一个3行6列的二维全1数组,元素类型是整型int
arr1 = np.ones((3,6), dtype=int)
# 创建一个包含6个0的一维数组,元素类型是整型int
arr2 = np.zeros(6, dtype=int)
np.vstack((arr1,arr2))

print(arr1)
print(arr2)
[[1 1 1 1 1 1]
 [1 1 1 1 1 1]
 [1 1 1 1 1 1]]
[0 0 0 0 0 0]

通过运行结果可以看出,原数组arr1和arr2没有发生改变,这就证明了vstack函数在垂直方向上合并两个数组,不会改变原数组,会生成一个新的数组,装这些合并之后的数据

 

沿水平方向合并

 

需求2:在水平方向上合并arr1和arr2

  上面我们提到了,在水平方向合并数组使用的函数是hstack,我们直接使用hstack函数在水平方向上合并arr1和arr2,看看能不能成功?     AI_3_0_4  
import numpy as np
x1=np.zeros((5,8),dtype=int)
x2=np.ones((5,1),dtype=int)
np.hstack((x1,x2))
结果合并失败,从报错信息可以非常清楚的看出,使用hstack函数在水平方向上合并两个数组的时候,要有相同的行数,只有两个数组的行数相同才能在水平方向拼接在一起。   由于arr1是二维数组包含3行数据,arr2是一维数组只有一行数据,这两个数组的维度不同行数不同,没法拼在一起。 水平方向的合并相当于把arr2的所有元素拆开,分成与arr1行数相同的等份,然后分别追加到arr1每行后面。 解决这个问题可以通过reshape函数改变arr2的形状,使它与arr1具有相同的行数之后,再合并。     AI_3_0_5  
import numpy as np

# 创建一个包含6个0的一维数组,元素类型是整型int
arr2 = np.zeros(6, dtype=int)

# 使用reshape函数,在arr2的基础上,生成一个包含3行数据的二维数组arr3,
arr3=np.ones((3,1))
# 新的数组arr3有多少列我不关心,由机器自动判断,所以我不需要设置新数组的列数
arr4 = arr2.reshape((3,-1))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-6b87de37272c> in <module>
      7 arr3=np.ones((3,1))
      8 # 新的数组arr3有多少列我不关心,由机器自动判断,所以我不需要设置新数组的列数
----> 9 arr4 = arr2.reshape((4,-1))

ValueError: cannot reshape array of size 6 into shape (4,newaxis)
数组arr3现在是一个3行2列的二维数组,将arr1与arr3在水平方向合并。     AI_3_0_6  
import numpy as np

# 创建一个3行6列的二维全1数组,元素类型是整型int
arr1 = np.ones((3,6), dtype=int)
# 创建一个包含6个0的一维数组,元素类型是整型int
arr2 = np.zeros(6, dtype=int)

np.hstack((arr1,arr2))
合并成功,hstack函数与vstack函数一样都不会对原数组进行更改,会生成一个新的数组。  

数组(矩阵)运算

  之前我们都是针对数组自身特点和功能的一些学习,在人工智能领域里,经常会用到科学计算,用的最多的就是数组(矩阵)运算。  

数组的加减乘除运算

  我们先从数组的加减乘除四则运算开始学起。     AI_3_0_7  
import numpy as np

# 创建一个包含0到9 十个元素的一维数组
x_arr = np.arange(10)
print(x_arr)
print("---------------------")

# x_arr内每个元素加1
print(x_arr + 1)
# x_arr内每个元素减1
print(x_arr - 2)
# x_arr内每个元素乘以2
print(x_arr * 2)
# x_arr内每个元素除以2
print(x_arr / 2)
[0 1 2 3 4 5 6 7 8 9]
---------------------
[ 1  2  3  4  5  6  7  8  9 10]
[-2 -1  0  1  2  3  4  5  6  7]
[ 0  2  4  6  8 10 12 14 16 18]
[0.  0.5 1.  1.5 2.  2.5 3.  3.5 4.  4.5]

在对numpy数组中的元素统一进行运算的时候,不需要使用循环遍历数组,numpy会自动对数组内的每个元素进行计算,使用起来非常方便,并且性能很高

  一维数组的运算法则对于二维数组同样适用,看下面的例子。     AI_3_0_8  
import numpy as np

# 创建一个3行4列的二维数组
x_arr2 = np.arange(1,13).reshape((3,4))
print(x_arr2)
print(x_arr2 * 2)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
[[ 2  4  6  8]
 [10 12 14 16]
 [18 20 22 24]]
接下来我们给numpy增加一些难度,对数组进行幂运算。  

数组的幂运算

 

新需求1:求数组中每个元素的平方

  AI_3_0_9  
import numpy as np

# 创建一个3行4列的二维数组
x_arr2 = np.arange(1,13).reshape((3,4))
print(x_arr2)
print("-------------------")
# 求数组中每个元素的平方
print(x_arr2 ** 2)
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
-------------------
[[  1   4   9  16]
 [ 25  36  49  64]
 [ 81 100 121 144]]

新需求2:自然常数e(e的值约等于2.71828)为底,分别以数组中的每个元素作为指数,打印出运算结果

 

numpy对自然常数e求幂运算提供了专属的函数exp,例如:e2e^2e​2​​使用exp求解:numpy.exp(2)

  AI_3_0_10  
import numpy as np

# 创建一维数组x_arr3=[0 1 2 3]
x_arr3= np.arange(0,4)

# 使用exp函数,分别计算以e为底,x_arr3中元素为指数的运算结果
print(np.exp(x_arr3))
[ 1.          2.71828183  7.3890561  20.08553692]
上面的例子程序最后输出了一个一维数组,数组里包含4个元素,每个元素分别对应以e为底,x_arr3数组中元素为指数的计算结果。    

数组的对数运算

  对数组中的元素进行对数运算,也就是幂的逆运算。  

我们知道2的3次方是8,幂运算表达式:23=82^3 = 82​3​​=8 。如果我不知道2的3次方是8,我只知道2的某次方是8,我要找2的多少次方是8,就要用幂的逆运算,
幂的逆运算表达式:log28=3\log_2{8} = 3log​2​​8=3 , 表示以2为底8的对数是3。

 

numpy提供了求解幂的逆运算log函数,默认情况下log函数是以e为底的,也就是log(x) 等价于 logex\log_e{x}log​e​​x

  我们知道e的0次方是1,那么以e为底1的对数就是0,我们来看看用log函数怎么实现。     AI_3_0_11  
import numpy as np

# 直接向log函数中传入参数1,就表示求以e为底1的对数
print(np.log(1))
0.0
接下来向log函数中传入一个数组,log函数会根据数组中的每一个元素求对数。

小提示:
e0e^0e​0​​ = 1 对应的幂的逆运算 log(1)log(1)log(1) = 0
e1e^1e​1​​ = e 对应的幂的逆运算 log(e)log(e)log(e) = 1

  AI_3_0_12  
import numpy as np

# 创建一个数组 [1,e]
x_arr4= np.array([1,np.e]) # np.e是numpy提供的自然常数e,我们可以直接使用

print(np.log(x_arr4))
[0. 1.]

新需求3:求以2为底8的对数

 

我们知道以2为底8的对数等于3,log28=3\log_2{8} = 3log​2​​8=3 ,numpy提供的log函数默认是以e为底,那我们应该怎么计算以2底的对数呢?

  答案很简单,换底就好了!看下面实现的代码:     AI_3_0_13    
import numpy as np

print(np.log2(8))

在numpy中,一维数组也被称为叫行向量,二维数组也被称为矩阵。上面我们讲的这些需求都是针对一个矩阵(数组)做运算,在后面的关卡中会涉及到一些机器学习算法实现,实现算法的过程经常会用到矩阵与矩阵之间的运算。

 

矩阵间四则运算

  接下来我们针对矩阵与矩阵的运算,看看numpy是怎么实现的。  

先看一个常见的例子:矩阵与矩阵之间的四则运算

 

下图是两个矩阵(二维数组)的运算过程,从图中可以看出,矩阵与矩阵之间的运算有两个注意点:

(1)两个矩阵的形状必须相同,也就是两个矩阵的行数和列数要相同;

(2)矩阵之间进行的运算是矩阵对应的元素之间进行计算。

    下面用代码实现矩阵的四则运算:     AI_3_0_14  
import numpy as np

# 创建一个2行3列的二维数组
X_a = np.arange(6).reshape((2,3))
print("X_a:")
print(X_a)

# 创建一个2行3列的全2 二维数组
X_b = np.full((2,3),2)
print("X_b:")
print(X_b)
print("-----------矩阵运算-------------")
print("X_a + X_b:")
print(X_a + X_b)

print("X_a - X_b :")
print(X_a - X_b)

print("X_a * X_b :")
print(X_a * X_b)

print("X_a / X_b :")
print(X_a / X_b)
X_a:
[[0 1 2]
 [3 4 5]]
X_b:
[[2 2 2]
 [2 2 2]]
-----------矩阵运算-------------
X_a + X_b:
[[2 3 4]
 [5 6 7]]
X_a - X_b :
[[-2 -1  0]
 [ 1  2  3]]
X_a * X_b :
[[ 0  2  4]
 [ 6  8 10]]
X_a / X_b :
[[0.  0.5 1. ]
 [1.5 2.  2.5]]
   

矩阵乘法

 

除了矩阵的四则运算,在机器学习中还经常使用矩阵乘法,numpy中有专门的dot函数处理矩阵乘法,注意:不是四则运算中的*乘。

 

两个矩阵的乘法有一个要求:矩阵A.dot(矩阵B),矩阵A的列数必须与矩阵B的行数相等

 

矩阵相乘的特点:一个m行n列的矩阵A与一个n行j列的矩阵B相乘的得到一个m行j列的矩阵。

  矩阵乘法的计算过程,以一个2行3列的矩阵X_a与一个3行2列的矩阵X_c相乘为例,最终得到一个2行2列的矩阵。     下面用代码实现上面矩阵相乘的过程。     AI_3_0_15  
import numpy as np

# 创建一个2行3列的二维数组
X_a = np.arange(6).reshape((2,3))
print(X_a)
print("--------------")
# 创建一个3行2列的二维数组
X_c = np.arange(6).reshape((3,2))
print(X_c)
print("--------------")
print(X_a.dot(X_c))
   

常用的统计函数

 

接下来我们来学习下numpy提供的求和、均值、最大值、最小值的函数,请点击下面的运行按钮,查看每个函数的运算结果。

  AI_3_0_16  
import numpy as np

X_a = np.arange(6).reshape((2,3))

print(X_a)
print("------------")

# 求矩阵中所有元素的和
print("sum: ", np.sum(X_a))

# 求矩阵中所有元素的均值
print("mean: ", np.mean(X_a))

# 求矩阵中所有元素的最大值
print("max: ", np.max(X_a))

# 求矩阵中所有元素的最小值
print("min: ", np.min(X_a))
[[0 1 2]
 [3 4 5]]
------------
sum:  15
mean:  2.5
max:  5
min:  0
   

简单的数据可视化

  我们在对数据做分析的时候,如果只看数据的一些数值、打印结果不能直观地看出数据具有哪些特征,数据能反映出哪些规律。所以需要配合可视化图形来分析数据。   numpy提供了一个简单易用,功能强大的画图工具包matplotlib,在使用matplotlib画图的时候,要通过import关键字引入这个工具包,在matplotlib包下有一个子模块pyplot,通常情况下我们会使用pyplot这个子模块进行画图。   下面我们使用matplotlib.pyplot画一些常用的图形。  

使用pyplot提供的plot函数画一个折线图

注意:使用pyplot画图,在所有的画图语句写完之后,在最后要调用pyplot的show函数用于把图形显示出来。

  AI_3_0_17  
import numpy as np
import matplotlib.pyplot as plt

# 一维数组x,使用numpy的linspace函数在[1,8]区间生成等间距的121个点,包含开头的1和结尾的8
x = np.linspace(1,8,121)

# 一维数组y,y数组内的每个元素与x数组中的对应元素有一种函数关系:y = (x - 4.5) ** 2 + 1
y = (x - 4.5) ** 2 + 1

# 我们知道x与y之间的函数关系:y = (x - 4.5) ** 2 + 1,是一条以x=4.5为对称轴的曲线
# 我们根据x与y之间的关系,画出这条曲线,plot函数的第3个参数color用于设置画出来的折线颜色(默认蓝色)
plt.plot(x, y, color="red")

# 设置图片标题(可选项)
plt.title("y = (x - 4.5) ** 2 + 1")

# 分别设置x轴、y轴显示的标签(可选项)
plt.xlabel("x")
plt.ylabel("y")

# 只有调用show函数才会把图形显示出来
plt.show()
使用pyplot提供的 scatter函数画一个 散点图。     AI_3_0_18
import numpy as np
import matplotlib.pyplot as plt

# 生成一个一维数组,存储每个点的横坐标
x = np.arange(10)
print(x)
# 生成一个一维数组,存储每个点的纵坐标,纵坐标y与x之间的关系:y = 2*x + 1
y = 2*x+1

# 画散点图
plt.scatter(x,y)

# 分别设置x轴、y轴显示的标签(可选项)
plt.xlabel("x")
plt.ylabel("y")

# 分别设置x、y坐标轴区间
plt.xlim(0,10)
plt.ylim(0,30)

plt.show
今天我们先到这里,拜拜~  

 

联系我们,一起学Python吧

分享Python实战代码,入门资料,进阶资料,基础语法,爬虫,数据分析,web网站,机器学习,深度学习等等。


​关注公众号「Python家庭」领取1024G整套教材、交流群学习、商务合作

标签:矩阵,print,苦练,arr2,数组,np,基本功,numpy
来源: https://blog.csdn.net/qq_34409973/article/details/114636514

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有