czy istnieje opcja, która nie powoduje mutacji oryginalnej tablicy, ale zwraca nową losową tablicę?
Charlie Parker
@Charlie Dobrze byłoby zadać osobne pytanie. (Może ktoś już o to pytał.)
David Z
13
Jak na ironię, ta strona jest największym hitem w Google, kiedy właśnie szukałem „tablicy shuffle python”
Joshua Huber,
2
@Charlie ludzie Google te pytania, aby mogli znaleźć odpowiedzi na nie w miejscach takich jak przepełnienie stosu. Dopóki nie jest to duplikat, nie ma nic złego w uczynieniu z przepełnienia stosu opcji jako zasobu
Matt
@javadba To właściwie miała być odpowiedź na pierwsze pytanie. Nie ma nic złego w zadawaniu pytań na temat przepełnienia stosu, nawet jeśli można go znaleźć przy kopaniu w google. Pozwala to przyszłym ludziom znaleźć odpowiedź na temat przepełnienia stosu podczas własnego kopania.
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)
Wynik:
[2,1,3]['two','one','three']
Korzyść: możesz losować wiele tablic jednocześnie, bez zakłócania mapowania. A „random_state” może kontrolować tasowanie w celu uzyskania powtarzalnego zachowania.
Dzięki, bardzo przydatne jest przetasowanie dwóch tablic jednocześnie.
Dmitry,
1
Szukałem tego, TNX!
nO
2
jest to bardziej kompletne (i często bardziej przydatne) niż zaakceptowana odpowiedź
javadba
21
Inne odpowiedzi są najłatwiejsze, jednak nieco denerwujące jest to, że random.shufflemetoda nic nie zwraca - po prostu sortuje podaną listę. Jeśli chcesz połączyć wywołania lub po prostu móc zadeklarować przetasowaną tablicę w jednym wierszu, możesz:
import random
def my_shuffle(array):
random.shuffle(array)return array
Następnie możesz wykonać linie takie jak:
for suit in my_shuffle(['hearts','spades','clubs','diamonds']):
Nie zwraca niczego specjalnie, ponieważ próbuje przypomnieć ci, że działa, zmieniając wprowadzone dane. (Może to zaoszczędzić pamięć.) Twoja funkcja zmienia również wprowadzane dane.
John Y,
2
Myślę, że to kwestia stylu. Osobiście wolę fakt, że mogę napisać jedną linię, aby osiągnąć to, co zajęłoby parę inaczej. Wydaje mi się dziwne, że język, który dąży do tego, aby programy były jak najkrótsze, nie zwraca w takich przypadkach zwracanego obiektu. Ponieważ zmienia on wprowadzone dane, możesz bez problemu wywołać wywołanie random.shuffle dla wywołania tej wersji.
Mark Rhodes,
12
Python tak naprawdę nie chce być tak krótki, jak to możliwe. Python dąży do zrównoważenia czytelności z ekspresją. Tak się składa, że jest dość krótki, głównie dlatego, że jest to język bardzo wysokiego poziomu. Wbudowane przez Pythona zazwyczaj (nie zawsze) starają się albo być „funkcjonalne” (zwracają wartość, ale nie mają efektów ubocznych), albo „proceduralne” (działają poprzez efekty uboczne i nic nie zwracają). Idzie to w parze z dość ścisłym rozróżnieniem Pythona między instrukcjami i wyrażeniami.
John Y,
Miły. Sugeruję zmienić nazwę na my_shuffle, aby natychmiast zobaczyć różnicę w kodzie.
Jabba
Może, ale może to być przedwczesna optymalizacja (może być pomocna, ale potrzeba przetasowania nie wymaga jawnego zwracania tablicy). Również losowanie (tablica), a następnie użycie losowania będzie składać się tylko z 2 wierszy, w przeciwieństwie do 3 + n (użycie razy), ale myślę, że byłoby to oszczędzanie, jeśli użyjesz go wiele razy. Oto świetny film, który omawia tego rodzaju rzeczy (np. Wymagania fantomowe i przedwczesna optymalizacja) - pyvideo.org/video/880/stop-writing-classes
Aaron Newton
12
W przypadku zwykłych list w języku Python random.shuffle()wykona zadanie dokładnie tak, jak pokazują poprzednie odpowiedzi.
Ale jeśli chodzi o ndarray( numpy.array), random.shufflewydaje się , że łamie oryginał ndarray. Oto przykład:
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 destroyedprint a
Po prostu użyj: np.random.shuffle(a)
Jak random.shuffle, np.random.shuffletasuje tablicę w miejscu.
czy tworzy to nowy losowy element dla każdego elementu tablicy?
javadba
@javadba Nie, po prostu posortuj tablicę według losowego indeksu, który ostatecznie przetasuje tablicę
Trinh Hoang Nhu
1
Niestety ja może nie usunąć nie znaczy, że arraymam na myśli Randomelementu: czyli w może być tworzenie nowych instancji klasy każdym razem. Nie jestem do końca pewien: w ten sposób byłby to niewłaściwy sposób: należy utworzyć a, a następnie wywołać . Ale nie jestem pewien, jak działa Pythonlambdarandom.random()RandomjavaRandom rng = Random()rng.nextGaussian()random.random()
javadba
1
Podczas gdy Twój kod może być poprawny jako odpowiedź, ale Opracowanie tego, co robi Twój kod, może poprawić jakość twojej odpowiedzi. Zapoznaj się z artykułem: Jak napisać dobrą odpowiedź?
LuFFy,
1
Oprócz poprzednich odpowiedzi chciałbym wprowadzić inną funkcję.
numpy.random.shufflea także random.shufflewykonywać tasowanie w miejscu. Jeśli jednak chcesz zwrócić tasowaną tablicę, skorzystaj z numpy.random.permutationtej funkcji.
tak, zwraca Brak, ale tablica jest zmodyfikowana, jeśli naprawdę chcesz coś zwrócić, zrób to importuj losowo def shuffle (arr): random.shuffle (arr) return arr
user781903
0
# arr = numpy array to shuffledef 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]
Należy pamiętać, że random.shuffle()nie należy go stosować w tablicach wielowymiarowych, ponieważ powoduje to powtórzenia.
Wyobraź sobie, że chcesz przetasować tablicę wzdłuż jej pierwszego wymiaru, możemy utworzyć następujący przykład testu:
import numpy as np
x = np.zeros((10,2,3))for i in range(10):
x[i,...]= i*np.ones((2,3))
tak, że wzdłuż pierwszej osi i-ty element odpowiada macierzy 2x3, w której wszystkie elementy są równe i.
Jeśli użyjemy prawidłowej funkcji losowania dla tablic wielowymiarowych, tzn np.random.shuffle(x). Tablica zostanie przetasowana wzdłuż pierwszej osi zgodnie z potrzebami. Jednak użycie random.shuffle(x)spowoduje powtórzenia. Możesz to sprawdzić, uruchamiając len(np.unique(x))po tasowaniu, co daje 10 (zgodnie z oczekiwaniami) z, np.random.shuffle()ale tylko około 5 podczas używania random.shuffle().
new_array = random.sample( array, len(array) )
.Odpowiedzi:
źródło
źródło
Alternatywny sposób to zrobić za pomocą sklearn
Wynik:
Korzyść: możesz losować wiele tablic jednocześnie, bez zakłócania mapowania. A „random_state” może kontrolować tasowanie w celu uzyskania powtarzalnego zachowania.
źródło
Inne odpowiedzi są najłatwiejsze, jednak nieco denerwujące jest to, że
random.shuffle
metoda nic nie zwraca - po prostu sortuje podaną listę. Jeśli chcesz połączyć wywołania lub po prostu móc zadeklarować przetasowaną tablicę w jednym wierszu, możesz:Następnie możesz wykonać linie takie jak:
źródło
W przypadku zwykłych list w języku Python
random.shuffle()
wykona zadanie dokładnie tak, jak pokazują poprzednie odpowiedzi.Ale jeśli chodzi o
ndarray
(numpy.array
),random.shuffle
wydaje się , że łamie oryginałndarray
. Oto przykład:Po prostu użyj:
np.random.shuffle(a)
Jak
random.shuffle
,np.random.shuffle
tasuje tablicę w miejscu.źródło
Na wypadek, gdybyś potrzebował nowej tablicy, której możesz użyć
sample
:źródło
Możesz posortować tablicę za pomocą losowego klucza
klucz można odczytać tylko raz, więc porównywanie pozycji podczas sortowania jest nadal skuteczne.
ale wygląda na to,
random.shuffle(array)
że będzie szybszy, ponieważ napisano w C.źródło
array
mam na myśliRandom
elementu: czyli w może być tworzenie nowych instancji klasy każdym razem. Nie jestem do końca pewien: w ten sposób byłby to niewłaściwy sposób: należy utworzyć a, a następnie wywołać . Ale nie jestem pewien, jak działa Pythonlambda
random.random()
Random
java
Random rng = Random()
rng.nextGaussian()
random.random()
Oprócz poprzednich odpowiedzi chciałbym wprowadzić inną funkcję.
numpy.random.shuffle
a takżerandom.shuffle
wykonywać tasowanie w miejscu. Jeśli jednak chcesz zwrócić tasowaną tablicę, skorzystaj znumpy.random.permutation
tej funkcji.źródło
Nie wiem, czy użyłem,
random.shuffle()
ale zwraca mi „Brak”, więc napisałem to, może komuś pomócźródło
źródło
Należy pamiętać, że
random.shuffle()
nie należy go stosować w tablicach wielowymiarowych, ponieważ powoduje to powtórzenia.Wyobraź sobie, że chcesz przetasować tablicę wzdłuż jej pierwszego wymiaru, możemy utworzyć następujący przykład testu:
tak, że wzdłuż pierwszej osi i-ty element odpowiada macierzy 2x3, w której wszystkie elementy są równe i.
Jeśli użyjemy prawidłowej funkcji losowania dla tablic wielowymiarowych, tzn
np.random.shuffle(x)
. Tablica zostanie przetasowana wzdłuż pierwszej osi zgodnie z potrzebami. Jednak użycierandom.shuffle(x)
spowoduje powtórzenia. Możesz to sprawdzić, uruchamiająclen(np.unique(x))
po tasowaniu, co daje 10 (zgodnie z oczekiwaniami) z,np.random.shuffle()
ale tylko około 5 podczas używaniarandom.shuffle()
.źródło