机器学习之科学计算库Numpy

发布时间 2023-10-01 07:05:05作者: strongmore

简介

在Python数据科学领域,Numpy是用得最广泛的工具包之一,基本上所有任务都能看到它的影子。在数据处理上非常实用,并且其底层函数都设计得十分高效,可以快速地进行数值计算。基本上后续要用到的其他和数据处理相关的工具包(如sklearn机器学习建模工具包)都是以Numpy为底层的。

通常来说,数据都可以转换成矩阵,行就是每一条样本数据,列就是其每个字段特征,Numpy在矩阵计算上非常高效,可以快速处理数据并进行数值计算。

数组

import numpy as np
array = np.array([1,2,3,4,5]) # 创建数组
array2 = array + 1 # 将数组中各个元素都执行+1操作
array2 + array # 对应位置进行计算 array([ 3,  5,  7,  9, 11])
array.shape  # 输出结果表示当前数组是一维的,其中有5个元素。 (5,)
np.array([[1,2,3],[4,5,6]]) # 创建二维数组
tang_array = np.array([1,2,3,4,'5']) # 一个元素为字符串类型,数组中的每个元素都变成字符串类型,浮点数结果也是如此。
tang_array.dtype # 当前数据类型 常见的数据类型有整型、浮点数和字符串等
tang_array.size # 当前数组中元素个数,如果是多维数组,累加
tang_array.ndim # 当前数据维度

索引与切片

import numpy as np
tang_array = np.array([1,2,3,4,5]) # 创建数组
tang_array[1:3] # 选择数组中索引值为1,2的元素 多维数据中也是同理
tang_array[-2:] # 从数组中倒数第二个数据开始取到最后
tang_array = np.array([[1,2,3],[4,5,6],[7,8,9]])
tang_array[:,0] # 取第一列全部元素
tang_array = np.arange(0,100,10) # 从0开始到100,每隔10个数取一个元素
mask = np.array([0,0,0,1,1,1,0,0,1,1],dtype=bool) # 创建了一个布尔类型的数组,0表示假,1表示真
tang_array[mask] # 获取索引位置为True的元素
random_array = np.random.rand(10) # 在[0,1)区间上随机选择10个数
mask = random_array > 0.5 # 判断其中每一个元素是否满足要求,返回布尔类型的数组
tang_array = np.array([10,20,30,40,50])
np.where(tang_array > 30) # 找到符合要求的索引位置 [3,4]
tang_array[np.where(tang_array > 30)] # 找到符合要求的元素 [40,50]
y = np.array([1,1,1,4])
x = np.array([1,1,1,2])
x == y # 元素依次比较,得到一个布尔类型的数组
np.logical_and(x,y) # 元素依次逻辑与
np.logical_or(x,y) # 元素依次逻辑或

数据类型与数值计算

tang_array = np.array([1,2,3,4,5],dtype=np.float32) # 创建数组的时候指定其数据类型
tang_array = np.array(['1','10','3.5','str'],dtype = np.object) # 指定数据类型为字符串
tang_array = np.array([1, 2, 3, 4, 5])
tang_array2 = np.asarray(tang_array,dtype = np.float32) # 类型转换 int->float
tang_array2 = tang_array.copy() # 数组拷贝
tang_array = np.array([[1,2,3],[4,5,6]])
np.sum(tang_array) # 全部元素求和
tang_array.sum() # 全部元素求和 两种写法
np.sum(tang_array,axis=0) # 对列求和
np.sum(tang_array,axis=1) # 对行求和
np.prod(tang_array) # 求乘积
np.min(tang_array) # 求最小值
np.mean(tang_array) # 求平均值
np.std(tang_array) # 求标准差
np.var(tang_array) # 求方差
np.argmin(tang_array) # 获取最小值的索引位置
tang_array = np.array([1.2,3.56,6.41])
tang_array.round() # 四舍五入 保留整数
tang_array.round(decimals=1) # 四舍五入 保留一位小数
x = np.array([5,5])
y = np.array([2,2])
np.multiply(x,y) # 对应位置元素相乘 [10,10]
np.dot(x,y) # 矩阵乘法 20,特殊:当x和y都是1维向量时,结果为两个向量的点积,5*2+5*2
  1. 当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘。
  2. 矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。
  3. 乘积C的第m行第n列的元素等于矩阵A的第m行的元素与矩阵B的第n列对应元素乘积之和。

image

image

image

常用功能模块

tang_array = np.array([[1.5,1.3,7.5], [5.6,7.8,1.2]])
np.sort(tang_array) # 排序  [1.3,1.5,7.5],[1.2,5.6,7.8]]
np.sort(tang_array,axis=0) # 按列排序 [[1.5,1.3,1.2],[5.6,7.8,7.5]]
np.argsort(tang_array) # [[1,0,2],[2,0,1]] 就是排序后的值在原数组中的位置
tang_array = np.linspace(0,10,10) # 在0-10之间产生等间隔的10个数
values = np.array([2.5,6.5,9.5])
np.searchsorted(tang_array,values) # 按照大小顺序把values插入刚创建的数组中的位置 [3,6,9]
tang_array = np.array([[1,0,6],[1,7,0],[2,3,1],[2,4,0]])
index = np.lexsort([-1*tang_array[:,0]]) # 得到按照第一列进行降序后的索引,–1表示降序 结果为[2,3,0,1]
tang_array[index] # 得到按照第一列降序之后的数组 [[2,3,1],[2,4,0],[1,0,6],[1,7,0]]
tang_array = np.arange(10) # 创建一个数组,0-10之间,间隔为1 [0,1,2,3,4,5,6,7,8,9]
tang_array.shape = 2,5 # 修改形状为2行5列 变换前后元素个数必须保持一致
tang_array = np.arange(10)
tang_array[np.newaxis,:] # 增加一个维度,原数组[0,1,2,3,4,5,6,7,8,9],变更后[[0,1,2,3,4,5,6,7,8,9]]
tang_array.squeeze() # 将多余的维度去掉 原数组[[[0,1,2,3,4,5,6,7,8,9]]],变更后[0,1,2,3,4,5,6,7,8,9]
tang_array = np.array([[0,1,2,3,4],[5,6,7,8,9]])
tang_array.transpose() # 行列互转,得到转置矩阵 [[0,5],[1,6],[2,7],[3,8],[4,9]]
tang_array.T # 得到转置矩阵

在Notebook中,直接执行变量名字就相当于打印操作,但是如果对变量计算或者处理操作时一定需要指定一个新的变量名,否则相当于只是打印而没有执行具体操作。

a = np.array([[1,2,3],[4,5,6]])
b = np.array([[7,8,9],[10,11,12]])
np.concatenate((a,b)) # 数组拼接 默认axis=0 拼接的方向上维度必须一致
np.concatenate((a,b),axis=1) # 数组拼接
d = np.array([1, 2, 3])
e = np.array([2, 3, 4])
np.stack((d, e)) # 创建一个新维度来拼接 [[1, 2, 3],[2, 3, 4]]
np.hstack((d, e)) # 水平方向上拼接 不会创建新维度
np.vstack((d, e)) # 垂直方向上拼接 维度为1时会创建新维度,大于等于2时,作用相当于concatenate,不会创建新维度
np.arange(2,20,2) # 在[2,20)区间上每隔2个数值取一个元素
# 2的1次方到2的10次方之间等比例出现的10个数字 [2.,4.,8.,16.,32.,64.,128.,256.,512.,1024.]
np.logspace(1,10,num=10,base=2)
np.r_[0:5:1] # 创建行向量 [0,1,2,3,4]
np.c_[0:5:1] # 创建列向量 [[0],[1],[2],[3],[4]]
np.zeros(3) # 创建零矩阵 [0,0,0]
np.zeros((3,3)) # 创建3x3的零矩阵 [[0,0,0],[0,0,0],[0,0,0]]
np.ones((3,3)) # 创建单位矩阵 和零矩阵类似 [[1,1,1],[1,1,1],[1,1,1]]
np.ones((3,3)) * 5 # 任意数值 [[5,5,5],[5,5,5],[5,5,5]]
a = np.empty(6) # 创建一个空数组 [0,0,0,0,0,0]
a.fill(1) # 用1填充
tang_array = np.array([[1,2,3],[4,5,6]])
np.zeros_like(tang_array)  # 初始化一个零矩阵,和指定数组的维度一致 [[0,0,0],[0,0,0]]
np.identity(3) # 创建3x3矩阵 对角线为1 [[1,0,0],[0,1,0],[0,0,1]]
np.random.rand(3,2) # 创建3x2矩阵 随机值0-1之间
np.random.randint(10,size = (5,4)) # 创建5x4矩阵 [0,10)之间的随机值
np.random.randint(0,10,3) # 创建数组 [0,10)之间3个值
np.random.rand() # 返回一个随机值
np.random.normal(0,0.1,10) # 符合均值为 0,标准差为 0.1 的高斯分布的随机数
np.set_printoptions(precision = 2) # 全局设置,保留2位小数
tang_array = np.arange(10)
np.random.shuffle(tang_array) # 数组洗牌
np.random.seed(100) # 指定随机种子
# Notebook 的魔法指令,相当于写了一个文件
%%writefile tang.txt
1 2 3 4 5 6
2 3 5 8 7 9
# 原生python读取文件
data = []
with open('tang.txt') as f:
    for line in f.readlines():
        fileds = line.split()
        cur_data = [float(x) for x in fileds]
        data.append(cur_data)
data = np.array(data)
# numpy读取文件
data = np.loadtxt('tang.txt')
data = np.loadtxt('tang2.txt',delimiter = ',') # 指定好分隔符
data = np.loadtxt('tang2.txt',delimiter = ',',skiprows = 1) # 指定去除前几行
data = np.loadtxt('tang2.txt',delimiter = ',',skiprows = 0,dtype=np.object) # 指定数据类型 默认为float
help(np.loadtxt) # 查看loadtxt函数文档
tang_array = np.array([[1,2,3],[4,5,6]])
np.savetxt('tang4.txt',tang_array,fmt='%d',delimiter = ',') # 将数据写入文件 指定数据格式和分隔符
np.save('tang_array.npy',tang_array) # 将数据保存成ndarray的格式 二进制格式
tang_array = np.load('tang_array.npy') # 读取npy格式文件

在数据处理过程中,中间的结果都保存在内存中,如果关闭Notebook或者重启IDE,再次使用的时候就要从头再来,十分耗时。如果能将中间结果保存下来,下次直接读取处理后的结果就非常高效,保存成.npy格式的方法非常实用。

对axis的理解

import numpy as np
b = np.array([[[1,2,3,4],[1,3,4,5]],[[2,4,7,5],[8,4,3,5]],[[2,5,7,3],[1,5,3,7]]])
#      [[[1, 2, 3, 4],
#        [1, 3, 4, 5]],
#
#       [[2, 4, 7, 5],
#        [8, 4, 3, 5]],
#
#       [[2, 5, 7, 3],
#        [1, 5, 3, 7]]]
b.sum(axis=0)
#      [[ 5, 11, 17, 12],
#       [10, 12, 10, 17]]
b.sum(axis=1)
#      [[ 2,  5,  7,  9],
#       [10,  8, 10, 10],
#       [ 3, 10, 10, 10]]
b.sum(axis=2)
#      [[10, 13],
#       [18, 20],
#       [17, 16]]

原数组为3维数组,axis可以看做数组层级,以b.sum(axis=2)为例,就是将第3层级的数据合并为一个值(计算和)

参考

numpy:高性能的矩阵计算-官方文档
Numpy:对Axis的理解