Mische ein Array mit Python und ordne die Reihenfolge der Array-Elemente mit Python nach dem Zufallsprinzip

261

Was ist der einfachste Weg, ein Array mit Python zu mischen?

davethegr8
quelle
28
+1 für die Migration der nützlichsten Teile der Python-Dokumentation in das immer überlegene SO Q & A-Format.
Charleslparker
1
Gibt es eine Option, die das ursprüngliche Array nicht mutiert, sondern ein neues gemischtes Array zurückgibt?
Charlie Parker
5
Sie können ein neues Array (unverändert) mit erhalten new_array = random.sample( array, len(array) ).
Charlie Parker

Antworten:

464
import random
random.shuffle(array)
David Z.
quelle
3
Gibt es eine Option, die das ursprüngliche Array nicht mutiert, sondern ein neues gemischtes Array zurückgibt?
Charlie Parker
@Charlie Das wäre eine gute Sache, in einer separaten Frage zu stellen. (Vielleicht hat es schon jemand anderes gefragt.)
David Z
13
Ironischerweise ist diese Seite der Top-Hit in Google, als ich gerade nach "Python Shuffle Array" gesucht habe
Joshua Huber
2
@ Charlie-Leute googeln diese Fragen, damit sie Antworten auf Fragen wie Stapelüberlauf finden können. Solange es sich nicht um ein Duplikat handelt, ist es nichts Falsches daran, den Stapelüberlauf zu einer Option als Ressource zu machen
Matt
@javadba Das sollte eigentlich eine Antwort auf die erste Frage sein. Es ist nichts Falsches daran, Fragen zum Stapelüberlauf zu stellen, selbst wenn dies bei einigen Grabungen bei Google gefunden werden könnte. Es ermöglicht zukünftigen Menschen, die Antwort auf den Stapelüberlauf zu finden, wenn sie selbst graben.
Matt
108
import random
random.shuffle(array)
Douglas Leeder
quelle
2
Gibt es eine Option, die das ursprüngliche Array nicht mutiert, sondern ein neues gemischtes Array zurückgibt?
Charlie Parker
36

Alternative Möglichkeit, dies mit sklearn zu tun

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)

Ausgabe:

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

Vorteil: Sie können mehrere Arrays gleichzeitig zufällig auswählen, ohne die Zuordnung zu stören. Und 'random_state' kann das Mischen für reproduzierbares Verhalten steuern.

Qy Zuo
quelle
1
Vielen Dank, es ist sehr nützlich, zwei Arrays gleichzeitig zu mischen.
Dmitry
1
War auf der Suche, TNX!
nOp
2
Dies ist vollständiger (und oft nützlicher) als die akzeptierte Antwort
Javadba
21

Die anderen Antworten sind die einfachsten, es ist jedoch etwas ärgerlich, dass die random.shuffleMethode eigentlich nichts zurückgibt - sie sortiert nur die angegebene Liste. Wenn Sie Anrufe verketten oder nur ein gemischtes Array in einer Zeile deklarieren möchten, haben Sie folgende Möglichkeiten:

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

Dann können Sie Zeilen wie:

    for suit in my_shuffle(['hearts', 'spades', 'clubs', 'diamonds']):
Mark Rhodes
quelle
7
Es gibt nichts spezielles zurück, weil es versucht, Sie daran zu erinnern, dass es funktioniert, indem es die Eingabe an Ort und Stelle ändert. (Dies kann Speicherplatz sparen.) Ihre Funktion ändert auch die Eingabe an Ort und Stelle.
John Y
2
Ich denke, es ist eine Stilsache. Persönlich bevorzuge ich die Tatsache, dass ich eine einzelne Zeile schreiben kann, um das zu erreichen, was ein Paar sonst brauchen würde. Es scheint mir seltsam, dass eine Sprache, die darauf abzielt, dass Programme so kurz wie möglich sind, in diesen Fällen nicht dazu neigt, das übergebene Objekt zurückzugeben. Da die Eingabe an Ort und Stelle geändert wird, können Sie einen Aufruf von random.shuffle für einen Aufruf dieser Version ohne Probleme ersetzen.
Mark Rhodes
12
Python möchte eigentlich nicht so kurz wie möglich sein. Python zielt darauf ab, Lesbarkeit mit Ausdruckskraft in Einklang zu bringen. Es ist also ziemlich kurz, hauptsächlich weil es eine sehr hohe Sprache ist. Pythons eigene integrierte Funktionen sind normalerweise (nicht immer) bestrebt, entweder "funktional" zu sein (einen Wert zurückzugeben, aber keine Nebenwirkungen zu haben) oder "prozedurähnlich" zu sein (über Nebenwirkungen zu arbeiten und nichts zurückzugeben). Dies geht Hand in Hand mit Pythons recht strenger Unterscheidung zwischen Aussagen und Ausdrücken.
John Y
Nett. Ich schlage vor, es in my_shuffle umzubenennen, um den Unterschied im Code sofort zu erkennen.
Jabba
Vielleicht, aber dies könnte eine vorzeitige Optimierung sein (es könnte hilfreich sein, aber die Notwendigkeit zu mischen erfordert nicht explizit die Notwendigkeit, das Array zurückzugeben). Außerdem würde Shuffle (Array), gefolgt von Shuffle, nur aus 2 Zeilen bestehen, im Gegensatz zu 3 + n (Times Use), obwohl ich denke, dass es eine Ersparnis wäre, wenn Sie es mehrmals verwenden. Hier ist ein großartiges Video, das diese Art von Dingen beschreibt (z. B. Phantomanforderungen und vorzeitige Optimierung) - pyvideo.org/video/880/stop-writing-classes
Aaron Newton
12

Beim Umgang mit regulären Python-Listen random.shuffle() erledigen Sie den Job genau so, wie die vorherigen Antworten zeigen.

Aber wenn es um ndarray( numpy.array) geht, random.shufflescheint das Original zu brechen ndarray. Hier ist ein Beispiel:

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

Benutz einfach: np.random.shuffle(a)

Wie random.shuffle, np.random.shufflemischt das Array an Ort und Stelle.

Shuai Zhang
quelle
2
Was bedeutet zerstört genau? (Ich meine, in diesem Zusammenhang - ich bin keine ELL.)
dbliss
Nun, wenn ich A = np.array (Bereich (9)) versuche. Umformen ([3,3])
Nicholas McCarthy
11

Nur für den Fall, dass Sie ein neues Array möchten, können Sie Folgendes verwenden sample:

import random
new_array = random.sample( array, len(array) )
Charlie Parker
quelle
3

Sie können Ihr Array mit einem zufälligen Schlüssel sortieren

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

Schlüssel nur einmal gelesen werden, so dass der Vergleich des Elements während der Sortierung immer noch effizient ist.

aber wie random.shuffle(array)es aussieht wird schneller sein, da es in C geschrieben ist

Trinh Hoang Nhu
quelle
1
Erstellt dies ein neues zufälliges Element für jedes Element des Arrays?
Javadba
@javadba Nein, dies sortiert nur ein Array nach einem zufälligen Index, der am Ende das Array mischen wird
Trinh Hoang Nhu
1
Tut mir leid, ich war mir vielleicht nicht klar, arrayich meinte nicht das ich meinte das RandomElement: dh in lambdader random.random()könnte Randomjedes Mal eine neue Klasseninstanz generiert werden. Ich bin mir eigentlich nicht sicher: javaDies wäre der falsche Weg: Sie sollten ein erstellen Random rng = Random()und dann das aufrufen rng.nextGaussian(). Aber nicht sicher, wie Python random.random()funktioniert
Javadba
1
Während Ihr Code möglicherweise als Antwort korrigiert wird, kann er die Qualität Ihrer Antwort verbessern. Kasse des Artikels: Wie schreibe ich eine gute Antwort?
LuFFy
1

Zusätzlich zu den vorherigen Antworten möchte ich eine weitere Funktion einführen.

numpy.random.shufflesowie random.shufflean Ort und Stelle mischen. Wenn Sie jedoch ein gemischtes Array zurückgeben möchten, müssen Sie diese numpy.random.permutationFunktion verwenden.

Säbel
quelle
1

Ich weiß nicht, ob ich es verwendet habe, random.shuffle()aber es gibt 'None' an mich zurück, also habe ich das geschrieben, könnte für jemanden hilfreich sein

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
Jeeva
quelle
2
Ja, es wird None zurückgegeben, aber das Array wird geändert. Wenn Sie wirklich etwas zurückgeben möchten, führen Sie diesen Import aus. random def shuffle (arr): random.shuffle (arr) return arr
user781903
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]
sudeep
quelle
0

Beachten Sie, dass random.shuffle() nicht für mehrdimensionale Arrays verwendet werden sollte, da dies zu Wiederholungen führt.

Stellen Sie sich vor, Sie möchten ein Array entlang seiner ersten Dimension mischen. Wir können das folgende Testbeispiel erstellen:

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

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

so dass entlang der ersten Achse das i-te Element einer 2x3-Matrix entspricht, in der alle Elemente gleich i sind.

Wenn wir die richtige Mischfunktion für mehrdimensionale Arrays verwenden, dh np.random.shuffle(x)das Array wird wie gewünscht entlang der ersten Achse gemischt. Die Verwendung random.shuffle(x)führt jedoch zu Wiederholungen. Sie können dies überprüfen, indem Sie len(np.unique(x))nach dem Mischen ausführen, was Ihnen 10 (wie erwartet) mit, np.random.shuffle()aber nur etwa 5 bei Verwendung ergibt random.shuffle().

Weise Wolke
quelle