这周借了本书,打算看看Python了,不知道会不会又半途而废,希望能够坚持下来,打算就是前面几章数据预处理,加上SVM的部分,感觉不多,希望这次真的可以坚持下来
今天先学习第一章:向量、矩阵和数组
这一章主要是用numpy库来实现对向量、矩阵、数组的基本操作,代码和注释基本都是来源于这本书的
#这是本书的第一章:向量、矩阵和数组——本章将介绍在进行机器学习的过程中可能经常遇到的numpy操作
######################################################################
#1.1 创建一个向量
#问题描述:创建一个向量
#加载库
import numpy as np #书中是numPy,但会报错没有这个模块
#创建一个行向量
vector_row=np.array([1,2,3])
#创建一个列向量
vector_column=np.array([[1],
[2],
[3]])
#####################################################################
#1.2 创建一个矩阵
#问题描述:创建一个向量
#加载库
import numpy as np #书中是numPy,但会报错没有这个模块
#创建一个矩阵
matrix=np.array([[1,2],
[1,2],
[1,2]])
#三行两列的矩阵,第1列都是1,第2列都是2
#实际上,numpy提供了专门的数据结构来表示矩阵
matrix_object=np.mat([[1,2],
[1,2],
[1,2]])
matrix=([[1,2],
[1,2],
[1,2]])
#虽然有专门的数据结构来表示矩阵,但是不建议使用矩阵数据结构,
#原因有二:1 数组才是numpy的标准数据结构 2绝大多数的numpy操作返回的是数组而不是矩阵对象
###########################################################################################
#1.3创建一个稀疏矩阵
#问题描述:高效地表示只有零星非零值的数据
#加载库
import numpy as np
from scipy import sparse
#创建一个矩阵
matrix=np.array([[0,0],
[0,1],
[3,0]])
#创建一个压缩的稀疏行(Compressed Sparse Row,CSR)矩阵
matrix_sparse=sparse.csr_matrix(matrix)
#查看稀疏矩阵
print(matrix_sparse)
#结果如下
# (1, 1) 1
# (2, 0) 3
#矩阵的下标从0开始,(1,1)代表第2行第2列元素非零。1表示值为1,(2, 0)代表第3行第1列元素非零。3表示值为3
#创建一个更大的矩阵
matrix_large=np.array([[0,0,0,0,0,0,0,0,0,0],
[0,1,0,0,0,0,0,0,0,0],
[3,0,0,0,0,0,0,0,0,0]])
#创建CSR矩阵
matrix_large=sparse.csr_matrix(matrix_large)
#查看原先的稀疏矩阵
print(matrix_sparse)
#查看更大的稀疏矩阵
print(matrix_large)
#可见,尽管实际上这个更大的矩阵中增加了很多非零的元素,但是它的表示和原来那个稀疏矩阵是一样的
#稀疏矩阵有很多种类型,不存在完美的稀疏矩阵,它们之间的差异都是有意义的,而且知道在什么场景下选择哪种类型
#的稀疏矩阵是很有必要的
###########################################################################################
#1.4选择元素
#问题描述:在向量或矩阵中,选择一个或多个元素
#加载库
import numpy as np
#创建一个行向量
vector = np.array([1,2,3,4,5,6])
#创建一个矩阵
matrix = np.array([[1,2,3],
[4,5,6],
[7,8,9]])
#选择向量的第三个元素
vector[2] #不会显示出来
print(vector[2]) #显示出来
#选择第2行第2列
matrix[1,1] #不会显示出来
print(matrix[1,1]) #显示出来
#讨论
#如同Python中的大多数事物一样,numpy数组的索引编号是从0开始的,这意味着第一个元素的下标是0而不是1
#除此之外,numpy还提供了很多方式来选取元素或数组中的一组元素(即索引和切片)
#选取所有的元素
vector[:] #不会显示出来
print(vector[:]) #显示出来
#结果:
# [1 2 3 4 5 6]
#选取从0开始一直到第3个(包含第3个元素)
vector[:3] #不会显示出来
print(vector[:3]) #显示出来
#结果:
# [1 2 3]
#选取第3个元素以后得所有元素
vector[3:] #不会显示出来
print(vector[3:]) #显示出来
#结果:
#[4 5 6]
#选取最后一个元素
vector[-1] #不会显示出来
print(vector[-1]) #显示出来
#结果:
#6
#选取矩阵的第1行和第2行以及所有列
matrix[:2,:] #不会显示出来
print(matrix[:2,:]) #显示出来
#结果:
# [[1 2 3]
# [4 5 6]]
#选取所有行以及第2列
matrix[:,1:2] #不会显示出来
print(matrix[:,1:2]) #显示出来
#结果:
# [[2]
# [5]
# [8]]
###########################################################################################
#1.5展示一个矩阵的属性
#问题描述:展示一个矩阵的形状大小和维数
#加载库
import numpy as np
#创建矩阵
matrix=np.array([[1,2,3,4],
[5,6,7,8],
[9,10,11,12]])
#查看航速和列数
matrix.shape #不会显示出来
print(matrix.shape) #显示出来
#结果:
# (3, 4)
#查看元素的数量(行数*列数)
matrix.size #不会显示出来
print(matrix.size) #显示出来
#结果:
# 12
#查看维数
matrix.ndim #不会显示出来
print(matrix.ndim) #显示出来
#结果:
# 2
#讨论
#虽然这些操作看起来很简单(确实也是这样,但是在做下一步计算之前或在某个操作之后,简单检查一下数组的形状
# 和大小是很有价值的)
#################################################################################
#1.6对多个元素同时应用某个操作
#问题描述:对一个数组中的多个元素同时应用某个函数
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,2,3],
[4,5,6],
[7,8,9]])
#创建一个函数,返回输入值加上100后的值
add_100=lambda i:i+100
#创建向量化函数
vectorized_add_100 =np.vectorize(add_100)
#对矩阵所有元素应用这个函数
vectorized_add_100(matrix) #不显示出来
print(vectorized_add_100(matrix)) #显示出来
#结果:
# [[101 102 103]
# [104 105 106]
# [107 108 109]]
#讨论
#numpy的vectorze类将一个函数转换成另一个函数,这个函数能把某个操作应用在数组的全部元素或一个切片上,
#值得注意的是,vectorize本质上是在对所有元素循环进行猴哥操作,所以并不会提升性能,此外,使用numpy的
# 数组,我们可以对两个维度不同的数组执行操作(这是一种叫做广播的方法)。举个例子,对于上述问题使用
# 广播后,我们的解决方案更加简单
#将所有的元素加上100
matrix +100
print(matrix +100)
#################################################################
#1.7找到最大值和最小值
#问题描述:计算一个数组的最大值和最小值
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,2,3],
[4,5,6],
[7,8,9]])
#返回最大的元素
np.max(matrix) #不会显示出来
print(np.max(matrix)) #显示出来
#返回最小的元素
np.min(matrix) #不会显示出来
print(np.min(matrix)) #显示出来
#讨论
#使用axis参数可以对一个特定的坐标轴应用此操作
#找到每一列最大的元素
np.max(matrix,axis=0) #不会显示出来
print(np.max(matrix,axis=0)) #显示出来
#找到每一行最大的元素
np.max(matrix,axis=1) #不会显示出来
print(np.max(matrix,axis=1)) #显示出来
###################################################################
#1.8计算平均值、方差和标准差
#问题描述:计算数组的一些描述性统计值
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,2,3],
[4,5,6],
[7,8,9]])
#返回平均值
np.mean(matrix)
print(np.mean(matrix))
#返回方差
np.var(matrix)
print(np.var(matrix))
#返回标准差
np.std(matrix)
print(np.std(matrix))
#讨论
#就如同使用min和max一样,我们可以计算出整个矩阵或其中一个坐标轴的描述性统计值
#求每一列的平均值
np.mean(matrix,axis=0)
print(np.mean(matrix,axis=0))
#结果
# [4. 5. 6.]
#求每一行的平均值
np.mean(matrix,axis=1)
print(np.mean(matrix,axis=1))
#结果
#[2. 5. 8.]
#######################################################################
#问题描述:在不改变元素值的前提下,改变一个数组的形状(行数和列数)
#加载库
import numpy as np
#创建一个4 x 3的矩阵
matrix=np.array([[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]])
#将该矩阵变形为2 x 6的矩阵
matrix.reshape(2,6)
print(matrix.reshape(2,6))
#讨论
#reshape 能传入一个非常有用的参数值 -1,表示可以“根据需要填充元素”,
# 所以reshape(1,-1)意味着矩阵的函数是1,列数则根据需要填充
matrix.reshape(1,-1)
print(matrix.reshape(1,-1))
##########################################################
#1.10转置向量或矩阵
#问题描述:转置一个向量或矩阵
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,2,3],
[4,5,6],
[7,8,9]])
#转置一个矩阵
matrix.T
print(matrix.T)
#讨论
#转置是线性代数中很常见的操作,它将每个元素的行、列下标互换
#严格意义上讲,一个向量是不能被转置的,因为它只是值的集合。
#将向量转置
np.array([1,2,3,4,5,6]).T
print(np.array([1,2,3,4,5,6]).T)
# 结果
# [1 2 3 4 5 6]
#转置一个行向量 (注意第2对括号)
np.array([[1,2,3,4,5,6]]).T
print(np.array([[1,2,3,4,5,6]]).T)
# 结果
# # [[1]
# # [2]
# # [3]
# # [4]
# # [5]
# # [6]]
###########################################################
#1.11展开一个矩阵
#问题描述:将矩阵转换为一个一维数组
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,2,3],
[4,5,6],
[7,8,9]])
#将矩阵展开
matrix.flatten()
print(matrix.flatten())
#讨论
#flatten是将矩阵转换为一维数组的一种简单方法,另一种是用reshape来构建一个行向量
matrix.reshape(1,-1)
print(matrix.reshape(1,-1))
###############################################################################
#计算矩阵的秩
#问题描述;计算一个矩阵的秩
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,1,1],
[1,1,10],
[1,1,15]])
#返回矩阵的秩
np.linalg.matrix_rank(matrix)
print(np.linalg.matrix_rank(matrix))
#讨论
#矩阵的秩就是由它的列或行展开的向量空间的维数,多亏由numpy的matrix_rank,计算一个矩阵的秩才能如此简单
#############################################################################################
#1.13计算行列式
#问题描述:计算一个矩阵的行列式
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,2,3],
[2,4,6],
[3,8,9]])
#返回矩阵的行列式
np.linalg.det(matrix)
print(np.linalg.det(matrix))
#讨论
#有时候矩阵的行列式是很有用的,使用numpy的det能够很容易计算出矩阵的行列式
########################################################################
#1.14获取矩阵的对角线元素
# 问题描述:获取矩阵的对角线元素
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,2,3],
[2,4,6],
[3,8,9]])
#返回对角线元素
matrix.diagonal()
print(matrix.diagonal())
#讨论
#我们还可以使用offset参数在主对角线的上下偏移,获取偏移后的对角线方向的元素:
# 返回对角线向上偏移量为1的对角线元素
matrix.diagonal(offset=1)
print(matrix.diagonal(offset=1))
# 返回对角线向下偏移量为1的对角线元素
matrix.diagonal(offset=-1)
print(matrix.diagonal(offset=-1))
############################################################################
#1.15计算矩阵的迹
#问题描述:计算一个矩阵的迹
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,2,3],
[2,4,6],
[3,8,9]])
#返回矩阵的迹
matrix.trace()
print(matrix.trace())
#讨论
#矩阵的迹是其对角线元素之和,我们还可以先返回矩阵的对角线元素,再对其求和来计算矩阵的迹
sum(matrix.diagonal())
print(sum(matrix.diagonal()))
#######################################################################
#1.16计算特征值和特征向量
#问题描述:计算一个方阵的特征值和特征向量
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,-1,3],
[1,1,6],
[3,8,9]])
#计算特征值和特征向量
eigenvalues,eigenvector=np.linalg.eig(matrix)
#查看特征值
eigenvalues
print(eigenvalues)
#查看特征向量
eigenvector
print(eigenvector)
#############################################################
#1.17计算点积
#问题描述:计算两个向量的点积
#加载库
import numpy as np
#创建两个向量
vector_a=np.array([1,2,3])
vector_b=np.array([4,5,6])
#计算点积
np.dot(vector_a,vector_b)
print(np.dot(vector_a,vector_b))
#讨论
#计算点积:在Python3.5以上的版本中使用新操作符@
vector_a @ vector_b
print(vector_a @ vector_b)
###############################################################
#1.18矩阵的相加或相减
#问题的描述:将两个矩阵相加或相减
#加载库
import numpy as np
#创建一个矩阵
matrix_a=np.array([[1,1,1],
[1,1,1],
[1,1,2]])
#创建另一个矩阵
matrix_b=np.array([[1,3,1],
[1,3,1],
[1,3,8]])
# 将两个矩阵相加
np.add(matrix_a,matrix_b)
print(np.add(matrix_a,matrix_b))
# 将两个矩阵相减
np.subtract(matrix_a,matrix_b)
print(np.subtract(matrix_a,matrix_b))
#讨论
#还可以简单地使用“+”和“-”操作符来实现矩阵的相加或相减
#将两个矩阵相加
matrix_a + matrix_b
print(matrix_a + matrix_b)
#将两个矩阵相减
matrix_a - matrix_b
print(matrix_a - matrix_b)
###############################################################
#1.19矩阵的乘法
#问题描述:将两个矩阵相乘
#加载库
import numpy as np
#创建一个矩阵
matrix_a=np.array([[1,1],
[1,2]])
#创建另一个矩阵
matrix_b=np.array([[1,3],
[1,2]])
#将两个矩阵相乘
np.dot(matrix_a,matrix_b)
print(np.dot(matrix_a,matrix_b))
#讨论
#还可以在Python3.5以上的版本中使用@操作符
matrix_a @ matrix_b
print(matrix_a @ matrix_b)
#结果:
# [[2 5]
# [3 7]]
#如果是想将两个矩阵对应的元素相乘,则需要使用*操作符
#让两个矩阵对应的元素相乘
matrix_a * matrix_b
print(matrix_a * matrix_b)
#结果:
# [[1 3]
# [1 4]]
###########################################################
#1.20计算矩阵的逆
#问题描述:计算一个方阵的逆
#加载库
import numpy as np
#加载库
import numpy as np
#创建一个矩阵
matrix=np.array([[1,4],
[2,5]])
#计算一个矩阵的逆
np.linalg.inv(matrix)
print(np.linalg.inv(matrix))
#讨论
#将一个矩阵和它的逆矩阵相乘,结果会是一个单位矩阵
matrix @ np.linalg.inv(matrix)
print(matrix @ np.linalg.inv(matrix))
#结果
# [[1. 0.]
# [0. 1.]]
####################################################################################
#1.21生成随机数
#问题描述:生成一些伪随机数
#加载库
import numpy as np
#设置随机数种子
np.random.seed(0)
#生成3个0.0到1.0之间的随机浮点数
np.random.random(3)
print(np.random.random(3))
#结果
# [0.54488318 0.4236548 0.64589411]
#使用相同的种子,产生相同的随机数
#讨论
#numpy提供了生成随机数的大量方法,对此更深入的讨论超出了本书的范围,
# 我们的解决方案中中生成的是浮点数,但是其实生成整数更常见
#生成3个1到10之间的随机整数
np.random.randint(0,11,3)
print(np.random.randint(0,11,3))
#或者可以从一个分布中随机抽取一些数来生成随机数
#从平均值是0.0,且标准差是1.0的正态分布中抽取3个数
np.random.normal(0.0,1.0,3)
print(np.random.normal(0.0,1.0,3))
#从平均值是0.0,且散布程度是1.0的logistic中抽取3个数
np.random.logistic(0.0,1.0,3)
print(np.random.logistic(0.0,1.0,3))
#从大于或等于1.0并且小于2.0的范围中抽取3个数
np.random.uniform(1.0,2.0,3)
print(np.random.uniform(1.0,2.0,3))
#最后 多次返回相同的随机数对于获取可预测、可重复的结果是很有用的,如果希望返回同样的随机数,
# 可以设置伪随机数生成器的“种子”(一个整数),如果在程序中用到了随机数,则拥有相同“种子”的程序会生成同样的
# 结果,对种子的使用会贯彻整本书,所以本书中使用“种子”的代码所生成的随机数,
# 与它们在你的电脑上运行产生的随机数是相同的。