飞桨课程中的Numpy简记


飞桨AI课程中附录《Numpy简介》的笔记,非常简明地给本小白上了一课所以做了笔记,方便自己查看。不过用惯了语雀的折叠块后看CSDN的md文档总觉得缺点啥。。所以也贴一个语雀的传送门好了 Numpy简介

Numpy基础功能:

  • ndarray数组:具有矢量算术运算和复杂广播能力的多维数组,特点是快速且节省空间;
  • 拥有对整组数据进行快速运算的标准数学函数(无需循环);
  • 具有线性代数、随机数生成、傅里叶变换功能;
  • 可读写磁盘数据、操作内存映射文件。

感觉正确理解使用这个包的前提是知道向量加减乘除应是什么结果。
举个栗子:从成都飞东京=从成都飞北京+从成都飞南京
什么两面包夹芝士!
简单粗暴的,这里放一个相对可信的学习链接:向量的加减

1. ndarray数组

1.1 为什么引入ndarray数组

  1. 其数组中所有元素的数据类型相同、数据地址连续、批量操作数组元素时速度更快
  2. 支持广播机制,矩阵运算无需for循环
  3. 底层使用C语言编写,内置并行计算功能,运行速度快于python
    向量的加减示例
# 实现a+1的计算(数组内全部+1)
import numpy as np
a = np.array([1,2,3,4,5])
a = a + 1
print(a)
# a = array([2,3,4,5,6])
# 实现c=a+b的计算(两数组的对应位置相加)
a = [1,2,3,4,5]
b = [2,3,4,5,6]
import numpy as np
a = np.array([1,2,3,4,5])
b = np.array([2,3,4,5,6])
c = a + b
print(c)
# c = array([3,5,7,9,11])

关于广播机制:其会按一定规则自动对数组的维度进行扩展以完成计算。

1.2 创建ndarray数组

可用四个函数进行创建:arrayarangezerosones
array:创建嵌套序列并转换为一个多维数组

# array
import numpy as np
a = [1,2,3,4,5]
b = np.array(a)
# b = array([1,2,3,4,5])

arange:创建元素从0到10依次递增2的数组

# arange
a = np.arange(0,10,2)
# a = array([0,2,4,6,8])
# zeros:创建指定长度或形状的全0数组。
a = np.zeros([3,3])
# a =  array([0.,0.,0.],
#			 [0.,0.,0.],
#			 [0.,0.,0.])
# ones:创建指定长度或形状的全1数组。
a = np.ones([3,3])
# a =  array([1.,1.,1.],
#			 [1.,1.,1.],
#			 [1.,1.,1.])

1.3 查看ndarray数组的属性

属性包括shapedtypesizendim等。

  • shape:数组形状,
  • dtype:数组中的数据类型
  • size:数组中包含的元素个数 ndarray.size,其大小等于各个维度的长度的乘积
  • ndim:数组的维度大小,ndarray.ndim,其大小等于ndarray.shape所含元素的个数
a = np.ones([3, 3])
print('a, dtype: {}, shape: {}, size: {}, ndim: {}'.format(a.dtype, a.shape, a.size, a.ndim))
# float64, (3,3), 9, 2

1.4 改变ndarray数组的数据类型和形状

# 改变数据类型
d = a.astype(np.int64)
# 改变形状
c = a.reshape([1,9])

1.5 ndarray数组的基本运算

1. 标量与 ndarray 数组之间的运算(加减乘除)

# 与标量的除等于用标量除以数组的每一个元素
arr = np.array([[1.,2.,3.],[4.,5.,6.]])
1.0 * arr
# array([1.,   0.5, 0.333333,],
#       [0.25, 0.2, 0.1666667])
# 与标量的乘等于标量乘以数组的每一个元素
arr = np.array([1.,2.,3.],[4.,5.,6.])
2.0 * arr
# array([[2.,4.,6.,],
#        [8.,10.,12.]])
# 与标量的加等于标量加上数组的每一个元素
arr = np.array([1.,2.,3.],[4.,5.,6.])
2.0 + arr
# array([[3.,4.,5.],
#        [6.,7.,8.]])
# 与标量的减等于标量减去数组的每一个元素
arr = np.array([1.,2.,3.],[4.,5.,6.])
2.0 - arr 
array([[1.,0.,-1.],
       [-2.,-3.,-4.]])

2. 两个ndarray数组之间的运算(加减乘除+开根号)

# 数组相减等于对应位置的元素相减
arr1 = np.array([[1.,2.,3.],[4.,5.,6.]])
arr2 = np.array([[11.,12.,13.],[21.,22.,23.]])
arr1 - arr2
# array([[-10.,-10.,10.],
#        [-17.,-17.,-17.]])
# 数组相加等于对应位置的元素相加
arr1 = np.array([[1.,2.,3.],[4.,5.,6.]])
arr2 = np.array([[11.,12.,13.],[21.,22.,23.]])
arr1 + arr2
# array([[11.,24.,39.],
#		[84.,110.,138.]])
# 数组相乘等于对应位置的元素相乘
arr1 * arr2
# array([[11.,24.,39.],
#        [84.,110.,138.]])
# 数组相除等于对应位置的元素相除
arr1 / arr2
# array([[0.09090909, 0.16666667, 0.23076923],
#        [0.19047619, 0.22727273, 0.26086957]])
# 数组开根号等于每个位置的元素都开根号
arr ** 0.5
# array([[1. , 1.41421356, 1.73205081],
#        [2. , 2.23606798, 2.44948974]])

1.6 ndarray数组的索引和切片

访问或修改某个位置:索引
访问或修改某个区域:切片
关键词:[-n,n-1]、slice函数、start,stop,step

1. 一维ndarray数组的索引和切片

  • 数组切片产生的新数组仍然指向原来的内存区域
  • 数据不会被复制
  • 视图上的任何修改都会直接反映到源数组上
  • 将一个标量赋值给切片时,会自动传播到整个选区
a = np.arrange(30)
a[10]
# 10
b = a[4:7]
# b = array([4,5,6])
a[4:7] = 10
# a = array([0,1,2,3,10,10,10,7,8,...29])
arr_slice = a[4:7]
arr_slice[0] = 100
# a = array([0,1,2,3,100,5,6,...29])
# arr_slice = array([100,5,6])

如果要使新数组拥有独立的内存空间,要使用copy

a = np.arange(30)
arr_slice = a[4:7]
arr_slice = np.copy(arr_slice)
arr_slice[0] = 100
# a = array([0,1,2,...,29])
# arr_slice = array([100,5,6])

2. 多维ndarray数组的索引和切片

特点

  • 各索引位置上的元素不再是标量而是多维数组
  • 以逗号隔开的索引列表来选取单个元素
  • 若省略后面的索引,则返回对象会是一个维度低一点的ndarray
a = np.arange(30)
arr3d = a.reshape(5, 3, 2)
# 可简单理解为将一维数组里的30个数字分为5排含3组每组含2数的排布。
arr3d = array([[[ 0, 1],[ 2, 3],[ 4, 5]],
               [[ 6, 7],[ 8, 9],[10, 11]],
               [[12, 13],[14, 15],[16, 17]],
               [[18, 19],[20, 21],[22, 23]],
               [[24, 25],[26, 27],[28, 29]]])
# 仅一个索引指标时,会在第0维索引,后面的维度保持不变
arr3d[0] = array([[0,1],[2,3],[4,5]])
# 两个索引时(单独式)
arr3d[0][1] = array([2,3])
# 两个索引时(区间式)
arr3d[0, 1] = array([2,3])

# ---------------------
# 切片
a = np.arange(24)
a = a.reshape([6,4])
# a 变形为 6 行 4 列的数组
[k for k in range(0,6,2)]
# [0,2,4]
slices = [a[k:k+2] for k in range(0,6,2)]

1.7 ndarray数组的统计方法

  1. mean:平均数
  2. std和var:标准差与方差
  3. sum:求和
  4. max和min:极大值,极小值
  5. argmax和argmin:极大值的索引,极小值的索引
  6. cumsum:所有元素的累加和
  7. cumprod:所有元素的累乘积
    以上方法中可使用参数如axis指定行,可以具体到使用时查看对应api

2. 随机数np.random

2.1 创建随机 ndarry 数组

含三部分内容

  • 随机数种子(一个种子跟一个随机数,一次一用,下次无效)
np.random.seed(10)
a = np.random.rand(3,3)
以上两行代码若同时选中再执行,就会出现与上一次执行相同的结果,如果去掉seed,则每次执行结果都会不一致。
在以上两行之后,若未再设置seed就执行rand,则该次rand生成的随机数也会每次都不一致。
  • 均匀分布(指定取值范围与数组形状)
np.random.uniform(low = -1.0, high = 1.0, size=(2, 2)
  • 正态分布(指定均值 loc 和方差 scale)
np.random.normal(loc = 1.0, scale = 1.0, size = (3, 3))

2.2 随机打乱ndarray数组顺序

随机打乱一维ndarray数组顺序

np.random.shuffle(a)

随机打乱二维ndarray数组顺序,则仅打乱行顺序,可理解为多维数组内最外层的数组才会打乱排序

2.3 随机选取元素

np.random.choice(a, size=5)

3. 线性代数

线性代数的矩阵乘法、矩阵分解、行列式以及其他方阵数学等是任何数组库的重要组成部分。在 numpy 中集成于 numpy.linalg 模块。常见使用有以下函数:

  • diag:以一维数组的形式返回方阵的对角线或非对角线元素,或将一维数组转换为方阵(非对角线元素为0)
  • dot:矩阵乘法
  • trace:计算对角线元素的和
  • det:计算矩阵行列式
  • eig:计算方阵的特征值和特征向量
  • inv:计算方阵的逆

dot 矩阵乘法
设矩阵 a 和 b ,b的第二维大小必须等于a的第一维大小

a = np.arange(12)
b = a.reshape([3,4])
c = a.reshape([4,3])
d = b.dot(c)

diag 转对角线元素

e = np.diag(d)
f = np.diag(e)

trace 计算对角线元素的和

g = np.trace(d)
g=440

det 计算行列式

h = np.linalg.det(d)

eig 计算特征值和特征向量

i = np.linalg.eig(d)

inv 计算方阵的逆

tmp = np.random.rand(3,3)
j = np.linalg.inv(tmp)

4. Numpy保存和导入文件

4.1 文件读写

d = np.fromfile(filepath,sep='分隔符')

d 是np数组

4.2 文件保存

np.save('文件名', 数据对象)#数组将直接保存为npy后缀的文件
b = np.load('文件名')#从磁盘文件读入数据
check = (a == b).all()#检查读取的文件与原始数据对象 a 是否一致
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值