Numpy中的两个乱序函数
乱序函数
在机器学习中为了防止模型学习到样本顺序这些影响泛化能力的特征,通常在模型进行训练之前打乱样本顺序。Numpy模块提供了permutation(x)
和shuffle(x)
两个乱序函数,permutation(x)
和shuffle(x)
两个函数都在 Numpy 的 random 模块下,因此要使用这两个乱序函数需要先导入 random 模块。
numpy.random.permutation(x)
permutation(x)
函数由传入的 x 参数的类型决定功能:
- 当 x 设置为标量时,返回指定范围值为 [0, x) 的乱序数组;
- 当 x 设置为数组(本文的所有数组指的都是ndarray数组)、列表以及元组时,则对数组、列表以及元组中的元素值进行乱序排列;
无论实现哪种功能,permutation(x)
函数最终返回的都是乱序后的数组。
import numpy as np
a = np.random.permutation(5) # x 为标量
b = np.random.permutation(np.arange(5)) # x 为数组
b2 = np.random.permutation([1, 2, 3, 4, 5]) # x 为列表
b3 = np.random.permutation((1, 2, 3, 4, 5)) # x 为元组
>>> print(f"the type of a:{type(a)}, a:{a}")
the type of a:<class 'numpy.ndarray'>, a:[1 4 2 0 3]
>>> print(f"the type of b:{type(b)}, b:{b}")
the type of b:<class 'numpy.ndarray'>, b:[0 1 3 4 2]
>>> print(f"the type of b2:{type(b2)}, b2:{b2}")
the type of b2:<class 'numpy.ndarray'>, b2:[1 3 5 4 2]
>>> print(f"the type of b3:{type(b3)}, b3:{b3}")
the type of b3:<class 'numpy.ndarray'>, b3:[3 1 4 2 5]
当 x 为标量时只能返回范围值为 [0, x) 乱序的一维数组,这是因为传入 x 为标量,相当于对numpy.arange(x)
数组进行乱序,因此返回的只能是一维数组。 但是如果传入的 x 为数组、列表以及元组时,我们可以指定数组、列表以及元组的维度,无论几个维度的数组、列表以及元组,permulation(x)
函数最终只对第一个维度进行乱序。
import numpy as np
b = np.arange(6).reshape(3, 2) # 原始的二维数组
# 使用乱序函数
b2 = np.random.permutation(b) # x 为二维数组
b3 = np.random.permutation(b.tolist()) # x 为二维列表, 通过 tolist 函数将数组转换列表
b4 = np.random.permutation(tuple(b.tolist())) # x 为二维元组(通常不会使用), 使用 tuple 函数将列表转换为元组
>>> print(b)
[[0 1]
[2 3]
[4 5]]
>>> print(b2)
[[4 5]
[2 3]
[0 1]]
>>> print(b3)
[[4 5]
[2 3]
[0 1]]
>>> print(b4)
[[0 1]
[2 3]
[4 5]]
这里以数组为例(列表和元组类似),对于二维数组:
- 第一个维度为
axis0
,表示沿着行方向; - 第二个维度为
axis1
,表示沿着列方向;
permulation(x)
函数对第一个维度进行乱序,也就是axis0
的行方向。假设现在原始二维数组为b
,乱序后的二维数组为b2
,permulation(x)
函数是如何沿着第一个维度进行乱序?
▲二维数组
沿着第一个维度进行乱序,沿着行方向进行乱序,我们将每一行都看成一个整体,每一个整体用相同颜色表示,不同整体用不同颜色进行区分。对第一个维度进行乱序,相当于对这些不同颜色的整体进行乱序。
此时原始的二维数组b = array([[0, 1], [2, 3], [4, 5]])
,是一个 3 行 4 列的二维数组,将每一行看成是一个整体,可以分成[0, 1]
, [2, 3]
和[4, 5]
三个整体,对其进行乱序相当于对这三个整体进行乱序,最终的乱序结果为b2 = array([[4, 5], [2, 3], [0, 1]])
。(因为乱序是随机的,有可能得到不同的乱序结果 )
random.shuffle(x)
shuffle(x)
函数中的参数 x 只能是数组或者列表(不能是元组)。shuffle(x)
函数并不返回乱序后的数组。
import numpy as np
a = np.arange(5) # 数组
>>> print(a) # 乱序前的 a 数组
[0 1 2 3 4]
a2 = np.random.shuffle(a)
>>> print(a) # 乱序后的 a 数组
[4 3 1 0 2]
>>> print(a2) # shuffle 函数不返回乱序后的数组
None
b = [0, 1, 2, 3, 4]
>>> print(b) # 乱序前的 b 列表
[0, 1, 2, 3, 4]
b2 = np.random.shuffle(b)
>>> print(b) # 乱序后的 b 列表
[0, 3, 4, 2, 1]
>>> print(b2) # shuffle 函数不返回乱序后的数组
None
上面的例子使用的都是一维数组或者一维列表,同样,我们可以指定数组和列表的维度,shuffle(x)
函数和permutation(x)
函数一样,无论几个维度的数组和列表,最终只对第一个维度进行乱序。关于shuffle(x)
函数对高维数组和列表的乱序处理这里不再赘述。
总结
下面通过一个表格对permutation(x)
和shuffle(x)
两个乱序函数进行一个简单的总结。
乱序函数 |
参数 x |
返回值 |
多维情况下的乱序 |
---|---|---|---|
permutation(x) |
1. 标量值;2. 数组、列表以及元组 |
乱序后的数组 |
只对第一个维度进行乱序 |
shuffle(x) |
1. 只能是数组或者列表(不能是元组) |
不返回乱序后的数组 |
只对第一个维度进行乱序 |
- 洛谷P1043 数字游戏
- 使用“空”对象替代引用是否为空判断
- 真是绝了!史上最详细的Jupyter Notebook入门教程
- 10.socket网络编程
- BZOJ1269: [AHOI2006]文本编辑器editor
- 开发人员为何需要企业服务总线?
- 搭建Visual Studio Code+Python开发环境1.对象简介2. 搭建步骤3.小结
- 洛谷P3835 【模板】可持久化平衡树
- 17.HTML
- 洛谷P2925 [USACO08DEC]干草出售Hay For Sale
- Numpy 修炼之道 (13)—— 将python函数向量化
- 洛谷P1887 乘积最大3
- 18.CSS
- R语言可视化——ggplot图表系统中的形状
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 二进制与十进制与十六进制介绍+转换+图解
- Swagger 3.0 官方 starter 诞生了,其它的都可以扔了~
- 原码+反码+补码概述与示范
- HTTP客户端连接,选择HttpClient还是OkHttp?
- 数据类型(基本数据类型和引用数据类型)范围与字符转换,代码示例+个位十位百位相加面试题
- Scanner关键字的使用+代码介绍+注意事项
- 将一个txt文件,复制到另一个txt文件中(缓冲字节流(BufferedInputStream,BufferedOutputStream))
- java实现客户端服务端互发消息并接收
- 使用NIO实现非阻塞式(相对的)多人聊天室
- 三次握手与四次挥手+图解
- 单例模式-->饿汉式+懒汉式
- 非常有必要了解的Springboot启动扩展点
- 冒泡排序图解+代码示例
- 使用prepareStatement连接数据库实现增、删、改、查
- 插入排序图解与代码示例