random.shuffle使用防坑

				版权声明: 891584158@qq.com					https://blog.csdn.net/qq_21063873/article/details/80860218				</div>
							<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57960eb32.css">
							            <div id="content_views" class="markdown_views prism-atom-one-dark">
						<!-- flowchart 箭头图标 勿删 -->
						<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg>
						<h1 id="有关randomshuffle函数的局限性">有关random.shuffle函数的局限性</h1>

刚刚踩的坑,记录一下,万一对别人有帮助呢。

本文重点: random.shuffle千万不要用于二维numpy.array(也就是矩阵)!!!

首先上证据

如下代码:

import random
import numpy as np
a = np.array([[1,2,3,4],
              [5,6,7,8]])
random.shuffle(a)
print(a)

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可能对应输出:

[[1 2 3 4]
 [1 2 3 4]]

 
 
  • 1
  • 2

得到一个错误输出!
查看random.shuffle源码:

    def shuffle(self, x, random=None):
    """Shuffle list x in place, and return None.

    Optional argument random is a 0-argument function returning a
    random float in [0.0, 1.0); if it is the default None, the
    standard random.random will be used.

    """

    if random is None:
        randbelow = self._randbelow
        for i in reversed(range(1, len(x))):
            # pick an element in x[:i+1] with which to exchange x[i]
            j = randbelow(i+1)
            x[i], x[j] = x[j], x[i]
    else:
        _int = int
        for i in reversed(range(1, len(x))):
            # pick an element in x[:i+1] with which to exchange x[i]
            j = _int(random() * (i+1))
            x[i], x[j] = x[j], x[i]

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

只需要关注其中交换元素操作为 x[i], x[j] = x[j], x[i] (好骚的操作,我之前不知道有这种写法)。

自己写个代码测试一下,这种交换方式对于二维numpy.array会发生什么事情:

import numpy as np
a = np.array([[1,2,3,4],
              [5,6,7,8]])
a[0], a[1] = a[1], a[0]
print(a)

 
 
  • 1
  • 2
  • 3
  • 4
  • 5

输出:

[[5 6 7 8]
 [5 6 7 8]]

 
 
  • 1
  • 2

显然这种方式不适合numpy.array的行交换(但是二维list就可以使用这种交换方式。可以自行证明,至于原因暂时不知道,求解答)。

打乱numpy.array正确的姿势当然是使用numpy自带的numpy.random.shuffle()

def shuffle(x): # real signature unknown; restored from __doc__
"""
shuffle(x)

        Modify a sequence in-place by shuffling its contents.

        This function only shuffles the array along the first axis of a
        multi-dimensional array. The order of sub-arrays is changed but
        their contents remains the same.

        Parameters
        ----------
        x : array_like
            The array or list to be shuffled.

        Returns
        -------
        None

        Examples
        --------
        >>> arr = np.arange(10)
        >>> np.random.shuffle(arr)
        >>> arr
        [1 7 5 2 9 4 3 6 0 8]

        Multi-dimensional arrays are only shuffled along the first axis:

        >>> arr = np.arange(9).reshape((3, 3))
        >>> np.random.shuffle(arr)
        >>> arr
        array([[3, 4, 5],
               [6, 7, 8],
               [0, 1, 2]])
"""
pass

 
 
  • 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
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

注释中Multi-dimensional arrays are only shuffled along the first axis: 多维向量只是沿着第一个坐标轴进行重新排序。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值