【问题标题】:Shuffling NumPy array along a given axis沿给定轴改组 NumPy 数组
【发布时间】:2011-06-29 18:34:33
【问题描述】:

给定以下 NumPy 数组,

> a = array([[1, 2, 3, 4, 5], [1, 2, 3, 4, 5],[1, 2, 3, 4, 5]])

洗牌很简单,

> shuffle(a[0])
> a
array([[4, 2, 1, 3, 5],[1, 2, 3, 4, 5],[1, 2, 3, 4, 5]])

是否可以使用索引符号来独立打乱每一行?还是您必须遍历数组。我想到了类似的东西,

> numpy.shuffle(a[:])
> a
array([[4, 2, 3, 5, 1],[3, 1, 4, 5, 2],[4, 2, 1, 3, 5]]) # Not the real output

虽然这显然行不通。

【问题讨论】:

    标签: python random numpy


    【解决方案1】:

    您必须多次调用numpy.random.shuffle(),因为您要独立地改组多个序列。 numpy.random.shuffle() 适用于任何可变序列,实际上不是ufunc。分别打乱二维数组a的所有行的最短和最有效的代码可能是

    list(map(numpy.random.shuffle, a))
    

    有些人更喜欢将其写成列表推导式:

    [numpy.random.shuffle(x) for x in a]
    

    【讨论】:

    • 谢谢,简单而干净的解决方案。
    • 至少对于python 3.5,numpy 1.10.2,这不起作用,a保持不变。
    • @drevicko:你的数组有什么维度?这个答案是为了洗牌二维数组的所有行(我相信它也适用于你的 Python 和 Numpy 版本的组合)。
    • 啊哈!我明白发生了什么:在 Python 3.5 中,map 是惰性的,会生成一个迭代器,并且在您迭代它之前不会进行映射。如果你这样做,例如:for _ in map(...): pass 它会起作用。
    • @drevicko 这是有道理的。那么最好将该代码编写为for x in a: numpy.random.shuffle(x)
    【解决方案2】:

    rand+argsort 技巧的矢量化解决方案

    我们可以沿指定轴生成唯一索引,并使用advanced-indexing 对输入数组进行索引。为了生成唯一索引,我们将使用random float generation + sort trick,从而为我们提供了一个矢量化解决方案。我们还将其推广到通用n-dim 数组以及通用axesnp.take_along_axis。最终的实现看起来像这样 -

    def shuffle_along_axis(a, axis):
        idx = np.random.rand(*a.shape).argsort(axis=axis)
        return np.take_along_axis(a,idx,axis=axis)
    

    请注意,此 shuffle 不会就地进行并返回一个 shuffle 的副本。

    示例运行 -

    In [33]: a
    Out[33]: 
    array([[18, 95, 45, 33],
           [40, 78, 31, 52],
           [75, 49, 42, 94]])
    
    In [34]: shuffle_along_axis(a, axis=0)
    Out[34]: 
    array([[75, 78, 42, 94],
           [40, 49, 45, 52],
           [18, 95, 31, 33]])
    
    In [35]: shuffle_along_axis(a, axis=1)
    Out[35]: 
    array([[45, 18, 33, 95],
           [31, 78, 52, 40],
           [42, 75, 94, 49]])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-13
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多