其他分享
首页 > 其他分享> > 第3关 苦练基本功(下)_numpy - 小象学院

第3关 苦练基本功(下)_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