使用python随机整理数组,使用python随机化数组项顺序


260

用python重组数组的最简单方法是什么?


28
+1,用于将python文档中最有用的部分迁移到始终具有优势的SO Q&A格式。
charleslparker 2013年

1
有没有不改变原始数组但返回新的改组数组的选项?
查理·帕克

5
您可以使用获得一个新数组(未修改)new_array = random.sample( array, len(array) )
查理·帕克

Answers:


463
import random
random.shuffle(array)

3
有没有不改变原始数组但返回新的改组数组的选项?
查理·帕克

@Charlie在一个单独的问题中问这将是一件好事。(也许有人已经问过了。)
David Z

13
具有讽刺意味的是,当我刚刚搜索“ python shuffle array”时,此页面在Google中排名最高
Joshua Huber

2
@Charlie people Google这些问题,以便他们可以在堆栈溢出之类的地方找到答案。只要不是重复项,就可以使堆栈溢出作为一种资源选项没有问题
Matt

@javadba实际上是要回答第一个问题。即使在Google上进行一些挖掘也可以找到有关堆栈溢出的问题,这没有错。它使将来的人们在自己进行挖掘时可以找到关于stackoverflow的答案。
马特


36

使用sklearn的另一种方法

from sklearn.utils import shuffle
X=[1,2,3]
y = ['one', 'two', 'three']
X, y = shuffle(X, y, random_state=0)
print(X)
print(y)

输出:

[2, 1, 3]
['two', 'one', 'three']

优点:您可以同时随机分配多个阵列,而不会破坏映射。并且“ random_state”可以控制改组以实现可重现的行为。


1
谢谢,一次混洗两个数组非常有用。
德米特里(Dmitry)

1
在寻找这个,TNX!
nOp

2
这比接受的答案更完整(并且通常更有用)
javadba

21

其他答案最简单,但是令人讨厌的是该random.shuffle方法实际上不返回任何内容,它只是对给定列表进行排序。如果要链接调用,或者只想在一行中声明一个改组数组,则可以执行以下操作:

    import random
    def my_shuffle(array):
        random.shuffle(array)
        return array

然后,您可以执行以下操作:

    for suit in my_shuffle(['hearts', 'spades', 'clubs', 'diamonds']):

7
它没有专门返回任何内容,因为它试图通过更改输入来提醒您它可以工作。(这样可以节省内存。)您的函数也会在适当位置更改其输入。
约翰Y

2
我想这是一件时尚的事。我个人更喜欢这样的事实:我可以写一行来达到其他目的。在我看来,一种旨在使程序尽可能短的语言在这种情况下不倾向于返回传递的对象,这似乎很奇怪。由于它会改变输入的位置,因此您可以将对random.shuffle的调用替换为对该版本的调用,而不会出现问题。
马克·罗德斯

12
实际上,Python并不旨在尽可能简短。Python旨在在可读性和表现力之间取得平衡。碰巧它是相当简短的,主要是因为它是一种非常高级的语言。Python的内置插件通常(并不总是)力争要么是“functionlike”(返回一个值,但没有副作用)或者是“procedurelike”(通过副作用操作,不返回任何东西)。这与Python在语句和表达式之间相当严格的区分是相辅相成的。
约翰Y

真好 我建议将其重命名为my_shuffle以立即查看代码中的差异。
加巴

也许可以,但是这可能是过早的优化(可能会有所帮助,但是洗牌的需求并不明确需要返回数组)。另外,shuffle(array)后面加上shuffle的某些用法只能是2行,而不是3 + n(次数用法),尽管我想如果您多次使用它会节省很多。这是一段精彩的视频,讨论了这类事情(例如幻影要求和过早的优化)-pyvideo.org/video/880/stop-writing-classes
Aaron

12

当处理常规的Python列表时,random.shuffle()将按照前面的答案所示进行操作。

但是,当谈到ndarraynumpy.array)时,random.shuffle似乎打破了原来的ndarray。这是一个例子:

import random
import numpy as np
import numpy.random

a = np.array([1,2,3,4,5,6])
a.shape = (3,2)
print a
random.shuffle(a) # a will definitely be destroyed
print a

只需使用: np.random.shuffle(a)

像一样random.shufflenp.random.shuffle就地调整数组的位置。


2
毁灭到底是什么意思?(我的意思是,在这种情况下-我不是ELL。)
dbliss '16

好吧,如果我尝试A = np.array(range(9))。reshape([3,3])
Nicholas McCarthy

11

万一您想要一个新的数组,可以使用sample

import random
new_array = random.sample( array, len(array) )

3

您可以使用随机键对数组进行排序

sorted(array, key = lambda x: random.random())

密钥只能读取一次,因此排序期间的比较项目仍然有效。

但是看起来好像random.shuffle(array)会更快,因为它是用C编写的


1
这会为数组的每个元素创建一个新的随机元素吗?
javadba

@javadba不,这只是按随机索引对数组进行排序,最终将使数组洗牌
Trinh Hoang Nhu

1
抱歉,我也许并不清楚我不是故意的array我的意思了 Random,即在:元素lambdarandom.random()可能会产生新的Random每次类实例。我实际上不确定:java这样做是错误的方式:您应该创建一个Random rng = Random()然后调用rng.nextGaussian()。但不确定python的random.random()工作方式
javadba

1
虽然您的代码可以正确地作为答案,但是详细说明您的代码可以做什么,它可以提高答案的质量。检出文章:如何写一个好的答案?
LuFFy

1

除了前面的答复,我还要介绍另一个功能。

numpy.random.shuffle以及random.shuffle执行就地改组。但是,如果要返回经过改组的数组,numpy.random.permutation则可以使用该函数。


1

我不知道我曾经用过,random.shuffle()但是它返回“ None”给我,所以我写了这个,可能对某人有帮助

def shuffle(arr):
    for n in range(len(arr) - 1):
        rnd = random.randint(0, (len(arr) - 1))
        val1 = arr[rnd]
        val2 = arr[rnd - 1]

        arr[rnd - 1] = val1
        arr[rnd] = val2

    return arr

2
是的,它返回None,但是数组被修改,如果您真的想返回某些东西,那么可以执行以下操作:import def def shuffle(arr):random.shuffle(arr)return arr
user781903 17-02-28

0
# arr = numpy array to shuffle

def shuffle(arr):
    a = numpy.arange(len(arr))
    b = numpy.empty(1)
    for i in range(len(arr)):
        sel = numpy.random.random_integers(0, high=len(a)-1, size=1)
        b = numpy.append(b, a[sel])
        a = numpy.delete(a, sel)
    b = b[1:].astype(int)
    return arr[b]

0

请注意,random.shuffle()不应在多维数组上使用它,因为它会引起重复。

假设您想沿数组的第一维进行混洗,我们可以创建以下测试示例,

import numpy as np
x = np.zeros((10, 2, 3))

for i in range(10):
   x[i, ...] = i*np.ones((2,3))

因此,沿着第一个轴,第i个元素对应于2x3矩阵,其中所有元素都等于i。

如果我们对多维数组使用正确的随机播放功能,即np.random.shuffle(x)该数组将根据需要沿第一个轴随机播放。但是,使用random.shuffle(x)会导致重复。您可以通过len(np.unique(x))在改组后运行来检查此问题,使用时可以得到10(按预期),np.random.shuffle()但使用时只有5 random.shuffle()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.