11 个令人惊叹的 NumPy Shuffle 示例

2023-10-25

蟒蛇的NumPy包提供了各种用于执行涉及随机性的操作的方法,例如从给定的数字列表中随机选择一个或多个数字的方法,或者生成给定范围内的随机数的方法,或者从给定分布。

所有这些方法均在randomNumPy 包的模块。
其中一种方法是numpy.random.shuffle method.
此方法用于随机打乱给定“可变”迭代的元素。
Note可迭代对象可变的原因是混洗操作涉及项目重新分配,而不可变对象不支持这一点。

 

洗牌有什么好处?

混洗操作对于许多应用程序来说是基础,在这些应用程序中,我们希望在处理给定的数据集时引入机会元素。
当我们希望避免在处理数据的顺序中引入任何类型的偏差时,它特别有用。

混洗操作通常用于批量处理数据的机器学习管道中。
每次从数据集中随机选择一个批次时,都会先进行洗牌操作。
它还可用于从给定集合中随机抽取项目而不进行替换。

 

如何打乱 NumPy 数组?

让我们看看它的基本用法np.random.shuffle method.
我们将打乱一个一维 NumPy 数组。


import numpy as np
for i in range(5):
    a=np.array([1,2,4,5,6])
    print(f"a = {a}")
    np.random.shuffle(a)
    print(f"shuffled a = {a}\n")
  

Output:

每次我们打电话shuffle方法,我们得到了不同顺序的数组a。

Note 运行此代码时得到的输出可能与我得到的输出不同,因为正如我们所讨论的,随机播放是一种随机操作。
在后面的部分中,我们将学习如何使这些随机操作具有确定性,以使结果可重现。

 

将多个 NumPy 数组混在一起

我们了解了如何打乱单个 NumPy 数组。有时我们想要将多个相同长度的数组以相同的顺序混在一起。
虽然shuffle方法不能接受超过 1 个数组,有一种方法可以通过使用 random 模块的另一个重要方法来实现这一点 -np.random.permutation.


x = np.array([1,2,3,4,5,6])
y = np.array([10,20,30,40,50,60])
print(f"x = {x}, y = {y}")
shuffled_indices = np.random.permutation(len(x)) #return a permutation of the indices
print(f"shuffled indices: {shuffled_indices}")
x = x[shuffled_indices]
y = y[shuffled_indices]
print(f"shuffled x  = {x}\nshuffled y {y}")
  

Output:

我们首先生成 [0, len(x)) 范围内整数值的随机排列,然后使用相同的排列来索引两个数组。

如果您正在寻找一种同时接受多个数组并对它们进行打乱的方法,那么 scikit-learn 包中就有一个 -sklearn.utils.shuffle.

此方法接受您想要打乱的任意数量的数组,并返回打乱后的数组。


from sklearn.utils import shuffle
x = np.array([1,2,3,4,5,6])
y = np.array([10,20,30,40,50,60])
x_shuffled, y_shuffled = shuffle(x,y)
print(f"shuffled x = {x_shuffled}\nshuffled y={y_shuffled}")
print(f"original x = {x}, original y = {y}")
  

Output:

请注意,此方法不会像np.random.shuffle相反,它返回打乱后的数组而不修改输入数组。
由于此方法不涉及就地项目重新分配,因此我们还可以使用此方法对不可变的可迭代对象进行洗牌。

 

打乱二维数组

我们已经看到了NumPy的效果shuffle一维数组上的方法。
让我们看看它对二维数组做了什么。


x = np.random.randint(1,100, size=(3,3))
print(f"x:\n{x}\n")
np.random.shuffle(x)
print(f"shuffled x:\n{x}")
  

Output:

如果仔细观察输出,会发现各行中值的顺序没有改变;然而,数组中行的位置已被打乱。
So the shuffle method 打乱行顺序默认情况下是二维数组。

 

打乱 2D NumPy 数组的列

我们在上一节中看到了shuffle二维数组上的方法。
它将数组的行就地打乱。

但是,如果我们想对数组的列进行打乱,该怎么办呢?
shuffle 方法不需要任何额外的参数来指定我们要执行 shuffle 的轴。

因此,如果我们想使用以下方法对 2D 数组的列进行打乱np.random.shuffle方法,我们必须找到一种方法将列视为行或将列与行交换.
这可以通过转置操作来实现。

我们将对 2D 数组的转置版本执行洗牌,并且由于洗牌就地发生,因此它将有效地对原始数组的列进行洗牌。


x = np.random.randint(1,100, size=(3,3))
print(f"x:\n{x}\n")
np.random.shuffle(x.T) #shuffling transposed form of x
print(f"column-wise shuffled x:\n{x}")
  

Output:

数组 x 的列现在已被打乱,而不是行。

 

打乱多维 NumPy 数组

我们已经看到了shuffle一维和二维数组上的方法。现在让我们尝试了解如果将更高维数组传递给此方法会发生什么。

让我们将一个 3 维数组传递给np.random.shuffle method.


x = np.random.randint(1,100, size=(4,3,3))
print(f"x:\n{x}\n")
np.random.shuffle(x) 
print(f"shuffled x:\n{x}")
  

Output:

这里各个 3×3 数组的位置已被打乱。

这种行为类似于我们在二维数组中观察到的行为。
The shuffle默认情况下,该方法会沿第一维(即 axis=0)对任何高维数组进行混洗。

沿轴随机播放

如果我们希望数组沿着任何其他轴进行洗牌,我们可以使用上一节中讨论的技术。
我们可以沿该轴生成索引的随机排列,并用它来索引数组。

让我们沿着轴 1 和轴 2 打乱 4x3x3 数组。


x = np.random.randint(1,100, size=(4,3,3))
print(f"x:\n{x}, shape={x.shape}\n")
indices_1 = np.random.permutation(x.shape[1])
x_1 = x[:,indices_1,:]
print(f"shuffled x along axis=1:\n{x_1}, shape={x_1.shape}\n")
indices_2 = np.random.permutation(x.shape[2])
x_2 = x[:,:,indices_2]
print(f"shuffled x along axis=2:\n{x_2}, shape={x_2.shape}\n")
  

Output:

在第一个输出中,当我们沿着 axis=1 进行洗牌时,每个 3×3 数组的行都已被洗牌。
类似地,当我们沿着 axis-2 进行洗牌时,数组的列也被洗牌了。

 

随机播放列表

在前面的章节中,我们讨论了其中一个条件np.random.shuffle工作的方法是输入必须是可变对象,因为该方法涉及就地项目重新分配。
任何洗牌方法起作用的另一个条件是输入对象必须是可下标的。这意味着可以使用输入的各个元素的位置或索引来识别和访问它们。

在Python提供的基本数据结构中,列表是唯一满足这两个条件的数据结构。
集合和字典是可变的,但不可下标。
元组和字符串是可下标的,但不可变。

让我们使用以下方法打乱 Python 列表np.random.shuffle method.


a = [5.4, 10.2, "hello", 9.8, 12, "world"]
print(f"a = {a}")
np.random.shuffle(a)
print(f"shuffle a = {a}")
  

Output:

如果我们想要对字符串或元组进行打乱,我们可以先将其转换为列表,打乱它,然后将其转换回字符串/元组;
或者我们可以使用 scikit-learnshuffle方法来获取它的打乱副本。

 

用种子洗牌

如果您在关注本博客时一直在实现代码片段,您一定已经注意到,执行随机播放操作后获得的结果与此处输出中显示的结果不同。
这是因为洗牌是随机操作,因此结果不可重现。

编程语言中的随机运算有不是真正随机的。这些操作是在一个伪随机数生成器,它是通过对称为“种子”的数字执行一系列数学运算而获得的。
如果我们在执行随机操作甚至一系列随机操作之前固定种子的值,则最终输出将变得确定,并且每次都可以使用相同的种子进行再现。

让我们回到我们在本博客中执行的第一个随机操作。
我们使用 for 循环将 NumPy 数组连续打乱五次,每次都会得到不同的输出。
现在让我们设置一个固定的随机种子每次在对原始数组进行洗牌之前,看看我们是否得到相同的输出或不同的输出。


for i in range(5):
    a=np.array([1,2,4,5,6])
    print(f"a = {a}")
    np.random.seed(42) #setting the random seed
    np.random.shuffle(a)
    print(f"shuffled a = {a}\n")
  

Output:

我们正在使用设置随机种子np.random.seed()每次调用之前np.random.shuffle使洗牌操作具有确定性。
但是,不必在每次调用随机操作之前设置随机种子。
如果您在代码中的不同实例中执行一系列随机操作之前设置一次随机种子;您可以稍后在另一天或另一台机器上通过在代码开头设置相同的种子来重现代码的输出。

 

打乱 NumPy 数组的维度

到目前为止,我们已经对 NumPy 数组执行了洗牌操作,而没有影响数组的形状。
我们一直在沿着选定的轴打乱数组的内容。

但是,如果我们想要打乱数组的轴而不是其元素怎么办?
NumPy 数组有一个名为转置,它接受轴索引的元组并根据传递的轴的顺序重塑数组。

让我们构建一个形状为 (2,3,2,4) 的 4 维数组,然后打乱其维度。


np.random.seed(0)
a = np.arange(48).reshape(2,3,2,4)
print(f"array a:\n{a}, shape={a.shape}\n")
shuffled_dimensions = np.random.permutation(a.ndim)
print(f"shuffled dimensions = {shuffled_dimensions}\n")
a_shuffled = a.transpose(shuffled_dimensions)
print(f"array a with shuffled dimensions:\n{a_shuffled}, shape={a_shuffled.shape}")
  

Output:

原始数组的形状为 (2,3,2,4)。
在我们打乱它的尺寸之后,它被转变为形状(2,4,3,2)。

 

随机播放与排列

我们已经在本博客的多个部分中看到了 NumPy 如何permutation方法可用于执行洗牌操作。
不仅np.random.permutation帮助以以下方式洗牌数组np.random.shuffle cannot,
但它也可以达到同样的结果shuffle在列表和数组上生成。

在本节中,我们将了解这两种方法之间的各种异同。

我们首先谈谈这两种方法可以接受的输入类型。
而 shuffle 方法严格只接受可下标、可变的迭代;permutation另一方面,接受不可变的可迭代对象和整数,以及可变的可迭代对象。
当你传递一个整数到np.random.permutation,它返回从 0 到该整数的整数范围的排列。


np.random.seed(42)
print(np.random.permutation(10))
  

Output:

接下来我们就来说一下这两个方法是如何进行shuffle操作的。
The shuffle方法对我们传递给该方法的原始可迭代对象执行就地改组,因此它返回无。所以原来的可迭代对象最终会被修改。
另一方面,permutation 始终返回 NumPy 数组无论输入类型如何,因此它不会修改原始输入可迭代。

Let us also compare the time it takes for the two methods to shuffle the same array.
We will run the two methods on the same array and log the time it takes for them to shuffle it.
We will log times for arrays of lengths ranging from 102 to 109, with increments of orders of 10.


import numpy as np
import time as time
permutation_time_log = []
shuffle_time_log = []
for i in range(2,10):
    print(f"shuffling array of length 10^{i}")
    a = np.random.randint(100, size=(10**i))
    t1 = time.time()
    np.random.permutation(a)
    t2 = time.time()
    permutation_time_log.append(t2-t1)
    t1 = time.time()
    np.random.shuffle(a)
    t2 = time.time()
    shuffle_time_log.append(t2-t1)
    del a
  

Note我们在每个循环结束时删除数组以释放内存;这可以避免以后迭代期间的任何内存开销。

我们记录了这两种方法对于长度递增的数组所消耗的时间。
现在让我们使用 pyplot 绘制它们。


import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,6))
ax  = fig.add_subplot(111)
ax.plot(permutation_time_log, label="permutation")
ax.plot(shuffle_time_log, label="shuffle")
ax.set_xlabel("length of array")
ax.set_ylabel("time for shuffling(s)")
ax.set_xticks(range(8))
ax.set_xticklabels([f"10^{i}" for i in range(2,10)])
ax.legend()
plt.show()
  

Output:

It is evident from the figure that the two methods take almost the same time for arrays up to length 108,
and the difference between their times becomes more prominent beyond this point.
For arrays of lengths higher than 108, the shuffle method performs shuffling faster than permutation,
and its performance over the latter becomes more significant with increasing lengths.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

11 个令人惊叹的 NumPy Shuffle 示例 的相关文章

  • 与区域指示符字符类匹配的 python 正则表达式

    我在 Mac 上使用 python 2 7 10 表情符号中的标志由一对表示区域指示符号 https en wikipedia org wiki Regional Indicator Symbol 我想编写一个 python 正则表达式来在
  • Python 中的舍入浮点问题

    我遇到了 np round np around 的问题 它没有正确舍入 我无法包含代码 因为当我手动设置值 而不是使用我的数据 时 返回有效 但这是输出 In 177 a Out 177 0 0099999998 In 178 np rou
  • Python getstatusoutput 替换不返回完整输出

    我发现了这个很棒的替代品getstatusoutput Python 2 中的函数在 Unix 和 Windows 上同样有效 不过我觉得这个方法有问题output被构建 它只返回输出的最后一行 但我不明白为什么 任何帮助都是极好的 def
  • 使用 Python 从文本中删除非英语单词

    我正在 python 上进行数据清理练习 我正在清理的文本包含我想删除的意大利语单词 我一直在网上搜索是否可以使用像 nltk 这样的工具包在 Python 上执行此操作 例如给出一些文本 Io andiamo to the beach w
  • 将 python2.7 与 Emacs 24.3 和 python-mode.el 一起使用

    我是 Emacs 新手 我正在尝试设置我的 python 环境 到目前为止 我已经了解到在 python 缓冲区中使用 python mode el C c C c将当前缓冲区的内容加载到交互式 python shell 中 显然使用了什么
  • 独立滚动矩阵的行

    我有一个矩阵 准确地说 是 2d numpy ndarray A np array 4 0 0 1 2 3 0 0 5 我想滚动每一行A根据另一个数组中的滚动值独立地 r np array 2 0 1 也就是说 我想这样做 print np
  • 使用字典映射数据帧索引

    为什么不df index map dict 工作就像df column name map dict 这是尝试使用index map的一个小例子 import pandas as pd df pd DataFrame one A 10 B 2
  • 立体太阳图 matplotlib 极坐标图 python

    我正在尝试创建一个与以下类似的简单的立体太阳路径图 http wiki naturalfrequent com wiki Sun Path Diagram http wiki naturalfrequency com wiki Sun Pa
  • 在Python中连接反斜杠

    我是 python 新手 所以如果这听起来很简单 请原谅我 我想加入一些变量来生成一条路径 像这样 AAAABBBBCCCC 2 2014 04 2014 04 01 csv Id TypeOfMachine year month year
  • datetime.datetime.now() 返回旧值

    我正在通过匹配日期查找 python 中的数据存储条目 我想要的是每天选择 今天 的条目 但由于某种原因 当我将代码上传到 gae 服务器时 它只能工作一天 第二天它仍然返回相同的值 例如当我上传代码并在 07 01 2014 执行它时 它
  • 使用 xlrd 打开 BytesIO (xlsx)

    我正在使用 Django 需要读取上传的 xlsx 文件的工作表和单元格 使用 xlrd 应该可以 但因为文件必须保留在内存中并且可能不会保存到我不知道如何继续的位置 本例中的起点是一个带有上传输入和提交按钮的网页 提交后 文件被捕获req
  • 如何在 Python 中解析和比较 ISO 8601 持续时间? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 Python v2 库 它允许我解析和比较 ISO 8601 持续时间may处于不同单
  • “隐藏”内置类对象、函数、代码等的名称和性质[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我很好奇模块中存在的类builtins无法直接访问的 例如 type lambda 0 name function of module
  • Docker 中的 Python 日志记录

    我正在 Ubuntu Web 服务器上的 Docker 容器中测试运行 python 脚本 我正在尝试查找由 Python Logger 模块生成的日志文件 下面是我的Python脚本 import time import logging
  • Numpy - 根据表示一维的坐标向量的条件替换数组中的值

    我有一个data多维数组 最后一个是距离 另一方面 我有距离向量r 例如 Data np ones 20 30 100 r np linspace 10 50 100 最后 我还有一个临界距离值列表 称为r0 使得 r0 shape Dat
  • pip 列出活动 virtualenv 中的全局包

    将 pip 从 1 4 x 升级到 1 5 后pip freeze输出我的全局安装 系统 软件包的列表 而不是我的 virtualenv 中安装的软件包的列表 我尝试再次降级到 1 4 但这并不能解决我的问题 这有点类似于这个问题 http
  • Python:XML 内所有标签名称中的字符串替换(将连字符替换为下划线)

    我有一个格式不太好的 XML 标签名称内有连字符 我想用下划线替换它 以便能够与 lxml objectify 一起使用 我想替换所有标签名称 包括嵌套的子标签 示例 XML
  • 将 Python 中的日期与日期时间进行比较

    所以我有一个日期列表 datetime date 2013 7 9 datetime date 2013 7 12 datetime date 2013 7 15 datetime date 2013 7 18 datetime date
  • 在 JavaScript 函数的 Django 模板中转义字符串参数

    我有一个 JavaScript 函数 它返回一组对象 return Func id name 例如 我在传递包含引号的字符串时遇到问题 Dr Seuss ABC BOOk 是无效语法 I tried name safe 但无济于事 有什么解
  • 使用随机放置的 NaN 创建示例 numpy 数组

    出于测试目的 我想创建一个M by Nnumpy 数组与c随机放置的 NaN import numpy as np M 10 N 5 c 15 A np random randn M N A mask np nan 我在创建时遇到问题mas

随机推荐

  • 如何在 Ubuntu 18.04 上设置或更改时区

    在 Ubuntu 上 系统的时区是在安装过程中设置的 但以后可以轻松更改 使用正确的时区对于许多与系统相关的任务和流程都很重要 例如 cron 守护进程使用系统的时区来执行 cron 作业 并且日志文件中的时间戳基于相同的时区 本教程演示如
  • 如何在 Debian 9 上安装 Yarn

    Yarn 是一个与 npm 兼容的 JavaScript 包管理器 它的创建是为了解决 npm 的一系列问题 例如通过并行操作加快软件包安装过程并减少与网络连接相关的错误 在本教程中 我们将指导您如何安装Yarn在 Debian 9 系统上
  • 如何在 Ubuntu 18.04 上安装 Django

    Django 是一个免费开源的高级 Python Web 框架 旨在帮助开发人员构建安全 可扩展和可维护的 Web 应用程序 有不同的方法来安装 Django 具体取决于您的需要 它可以在系统范围内安装 也可以使用 pip 安装在 Pyth
  • 如何在 Linux 中添加目录到 PATH

    当您在命令行上键入命令时 您基本上是在告诉 shell 运行具有给定名称的可执行文件 在Linux中 这些可执行程序就像ls find file和其他文件 通常位于系统上的几个不同目录中 存储在这些目录中的任何具有可执行权限的文件都可以从任
  • 如何在 CentOS 8 上设置或更改时区

    使用正确的时区对于许多与系统相关的任务和流程至关重要 例如 cron 守护进程使用系统的时区来执行 cron 作业 并且日志文件中的时间戳基于同一系统的时区 在 CentOS 上 系统的时区是在安装过程中设置的 但以后可以轻松更改 本文介绍
  • Python range() 函数

    蟒蛇rangetype 通过定义范围的起点和终点来生成整数序列 它通常与for循环迭代数字序列 range 在 Python 2 和 3 中的工作方式有所不同 在Python 2中 有两个函数可以让你生成整数序列 range and xra
  • Linux 中的正常运行时间命令

    在本教程中 我们将介绍uptime命令 顾名思义 uptime命令显示系统已经运行了多长时间 它还显示当前时间 登录用户数以及过去 1 5 和 15 分钟的系统负载平均值 如何使用正常运行时间命令 uptime 命令的语法如下 uptime
  • 如何在 CentOS 7 上使用 VSFTPD 设置 FTP 服务器

    FTP 文件传输协议 是一种标准的客户端 服务器网络协议 允许用户在远程网络之间传输文件 有多种可用于 Linux 的开源 FTP 服务器 最流行和最广泛使用的是PureFTPd ProFTPD and vsftpd 在本教程中 我们将在
  • Python while 循环

    循环是编程语言的基本概念之一 当您想要多次重复特定的代码块直到满足给定条件时 循环会很方便 Python中有两种基本的循环结构 for and while loops 本教程涵盖了以下基础知识whilePython 中的循环 我们还将向您展
  • NumPy loadtxt 教程(从文件加载数据)

    在之前的教程中 我们讨论过NumPy 数组 我们看到了它如何使读取 解析和对数字数据执行操作的过程变得轻而易举 在本教程中 我们将讨论 NumPy loadtxt 方法 该方法用于解析文本文件中的数据并将其存储在 n 维 NumPy 数组中
  • Linux Bash 脚本编写第 3 部分 – 参数和选项

    到目前为止 您已经了解了如何编写无需用户输入即可完成工作的 Linux bash 脚本 今天我们将继续我们的 Linux bash 脚本系列 如果您想了解我们在谈论什么 我建议您查看之前的帖子 Bash 脚本基础知识 Bash 脚本 For
  • Pythonnamedtuple(将元组提升到一个新的水平)

    在本教程中 我们将深入研究命名元组 它们是什么 如何创建和操作它们 以及何时使用它们 或不使用它们 命名元组是Python内置的一部分收藏模块 并且它们提供了一种将数据捆绑在一个名称下的便捷方法 它们是 Python 内置元组数据类型的子类
  • 使用 Python 处理 CSV:综合教程

    CSV 逗号分隔值 文件是存储和共享表格数据的最常见方法之一 这些文件由行和列组成 其中每行代表一个记录 列包含由分隔符 通常是逗号 分隔的值 Python 提供了多种内置方法来处理 CSV 文件 使您可以高效地读取 写入和操作数据 本教程
  • Linux Bash 脚本编写第 5 部分 – 信号和作业

    在上一篇文章中 我们谈到了输入 输出和重定向在 bash 脚本中 今天我们将学习如何在Linux系统上运行和控制它们 到目前为止 我们只能从命令行界面运行脚本 但这并不是运行 Linux bash 脚本的唯一方法 这篇文章描述了控制 Lin
  • 使用curl命令的SSL/TLS:安全连接指南

    卷曲命令是一种发出网络请求的工具 它在通过 HTTPS 与安全服务器通信时使用 SSL TLS 默认情况下 curl尝试在可用时使用安全连接 但了解如何控制和诊断这些连接至关重要 目录 hide 1 使用客户端证书 2 指定证书类型 3 使
  • 如何使用 tqdm 创建 Python 终端进度条?

    进度条是估算和显示任务所需时间的宝贵工具 这些也可以添加到您的 Python 脚本或代码块中 以指示代码执行所需的时间 Python 中有多种可用的库 例如progressbar and tqdm可以用于此目的 目录 hide 1 什么是
  • 使用 Linux curl 命令管理 Cookie

    与 Web 应用程序交互时 您会遇到处理 cookie 和会话的需要 在本教程中 您将学习如何使用卷曲命令发送 接收和管理 cookie 目录 hide 1 手动发送 Cookie 标头 2 存储从服务器接收到的 Cookie 3 通过请求
  • 正确理解 Linux 运行级别

    您可以将 Linux 运行级别视为操作系统运行的不同 模式 每种模式或运行级别都有其打开或关闭的进程和服务列表 从 Linux 启动时起 它就始终处于某个运行级别 当您继续使用计算机时 此运行级别可能会发生变化 具体取决于操作系统需要访问的
  • Linux PS1 提示定制终极指南

    PS1 或提示字符串 1 是主要提示变量 它定义 Linux shell 环境中命令行提示的外观和元素 它提供了多个自定义选项 使您的命令提示符信息更丰富且更具视觉吸引力 本教程将讨论这些细节 增强您的命令行界面体验 目录 hide 1 查
  • 11 个令人惊叹的 NumPy Shuffle 示例

    蟒蛇的NumPy包提供了各种用于执行涉及随机性的操作的方法 例如从给定的数字列表中随机选择一个或多个数字的方法 或者生成给定范围内的随机数的方法 或者从给定分布 所有这些方法均在randomNumPy 包的模块 其中一种方法是numpy r