Acak array dengan python, acak urutan item array dengan python


261

Apa cara termudah untuk mengocok array dengan python?


28
+1 untuk memigrasi bit paling berguna dari dokumentasi python ke format SO Q&A yang selalu unggul.
charleslparker

1
apakah ada opsi yang tidak mengubah array asli tetapi mengembalikan array yang diacak baru?
Charlie Parker

5
Anda bisa mendapatkan array baru (tidak dimodifikasi) dengan new_array = random.sample( array, len(array) ).
Charlie Parker

Jawaban:


464
import random
random.shuffle(array)

3
apakah ada opsi yang tidak mengubah array asli tetapi mengembalikan array yang diacak baru?
Charlie Parker

@ Charlie Itu akan menjadi hal yang baik untuk ditanyakan dalam pertanyaan terpisah. (Mungkin orang lain sudah menanyakannya.)
David Z

13
Ironisnya, halaman ini adalah hit teratas di Google ketika saya baru saja mencari "python shuffle array"
Joshua Huber

2
@Charlie orang Google pertanyaan ini sehingga mereka dapat menemukan jawaban mereka di tempat-tempat seperti stack overflow. Selama ini bukan duplikat, tidak ada yang salah dengan menjadikan stack overflow sebagai sumber daya
Matt

@javadba Itu sebenarnya dimaksudkan sebagai balasan untuk pertanyaan pertama. Tidak ada yang salah dengan mengajukan pertanyaan tentang stack overflow bahkan jika itu dapat ditemukan dengan beberapa penggalian di google. Ini memungkinkan orang di masa depan untuk menemukan jawaban pada stackoverflow ketika mereka melakukan penggalian sendiri.
Matt


36

Cara alternatif untuk melakukan ini menggunakan 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)

Keluaran:

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

Keuntungan: Anda dapat mengacak banyak array secara bersamaan tanpa mengganggu pemetaan. Dan 'random_state' dapat mengontrol pengocokan untuk perilaku yang dapat direproduksi.


1
Terima kasih, ini sangat berguna untuk mengocok dua array sekaligus.
Dmitry

1
Sedang mencari ini, TNX!
ada

2
ini lebih lengkap (dan seringkali lebih bermanfaat) daripada jawaban yang diterima
javadba

21

Jawaban lainnya adalah yang termudah, namun agak menjengkelkan bahwa random.shufflemetode ini tidak mengembalikan apa pun - hanya mengurutkan daftar yang diberikan. Jika Anda ingin membuat panggilan atau hanya dapat mendeklarasikan array yang diacak dalam satu baris, Anda dapat melakukannya:

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

Maka Anda dapat melakukan baris seperti:

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

7
Itu tidak mengembalikan apa pun secara khusus karena berusaha mengingatkan Anda bahwa itu berfungsi dengan mengubah input yang ada. (Ini dapat menghemat memori.) Fungsi Anda juga mengubah inputnya.
John Y

2
Saya kira itu hal gaya. Secara pribadi saya lebih suka fakta bahwa saya dapat menulis satu baris untuk mencapai apa yang akan mengambil pasangan sebaliknya. Rasanya aneh bagi saya bahwa bahasa yang bertujuan untuk memungkinkan program sesingkat mungkin tidak cenderung mengembalikan objek yang lewat dalam kasus ini. Karena itu mengubah input di tempat, Anda dapat mengganti panggilan ke random.shuffle untuk panggilan ke versi ini tanpa masalah.
Mark Rhodes

12
Python sebenarnya tidak bertujuan untuk sesingkat mungkin. Python bertujuan untuk menyeimbangkan keterbacaan dengan ekspresivitas. Kebetulan itu cukup singkat, terutama karena itu adalah bahasa tingkat yang sangat tinggi. Python sendiri built-in biasanya (tidak selalu) berusaha untuk baik menjadi "functionlike" (mengembalikan nilai, tetapi tidak memiliki efek samping) atau menjadi "procedurelike" (beroperasi melalui efek samping, dan tidak kembali apa-apa). Ini sejalan dengan perbedaan Python yang cukup ketat antara pernyataan dan ekspresi.
John Y

Bagus. Saya sarankan mengubah nama menjadi my_shuffle untuk melihat perbedaan dalam kode segera.
Jabba

Mungkin, tapi ini bisa jadi optimasi prematur (mungkin bisa membantu, tetapi kebutuhan untuk mengacak tidak secara eksplisit mengharuskan perlunya mengembalikan array). Juga, shuffle (array) diikuti oleh beberapa penggunaan shuffle hanya akan menjadi 2 baris dibandingkan dengan 3 + n (kali penggunaan), meskipun saya kira itu akan menjadi penghematan jika Anda menggunakannya berkali-kali. Berikut ini adalah video hebat yang membahas hal semacam ini (misalnya persyaratan hantu dan optimisasi prematur) - pyvideo.org/video/880/stop-writing-classes
Aaron Newton

12

Ketika berhadapan dengan daftar Python biasa, random.shuffle()akan melakukan pekerjaan seperti yang ditunjukkan oleh jawaban sebelumnya.

Tetapi ketika datang ke ndarray( numpy.array), random.shuffletampaknya melanggar aslinya ndarray. Berikut ini sebuah contoh:

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

Cukup gunakan: np.random.shuffle(a)

Seperti random.shuffle, np.random.shufflemengocok array di tempat.


2
apa artinya dihancurkan, tepatnya? (maksud saya, dalam konteks ini - saya bukan ELL.)
dbliss

Nah jika saya mencoba A = np.array (range (9)). Membentuk kembali ([3,3])
Nicholas McCarthy

11

Jika Anda menginginkan array baru, Anda dapat menggunakan sample:

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

3

Anda dapat mengurutkan array dengan kunci acak

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

kunci hanya dapat dibaca sekali sehingga membandingkan item selama sortir masih efisien.

tapi sepertinya random.shuffle(array)akan lebih cepat karena ditulis dalam C


1
apakah ini membuat elemen acak baru untuk setiap elemen array?
javadba

@javadba Tidak, ini hanya mengurutkan array dengan indeks acak yang akhirnya akan mengocok array
Trinh Hoang Nhu

1
Maaf saya mungkin tidak jelas saya tidak berarti arraysaya berarti Randomelemen: yaitu di lambdadalam random.random()mungkin menghasilkan baru Randomkelas misalnya setiap kali. Saya sebenarnya tidak yakin: dalam javahal ini akan menjadi cara yang salah untuk melakukannya: Anda harus membuat Random rng = Random()dan kemudian memohon rng.nextGaussian(). Tetapi tidak yakin bagaimana python random.random()bekerja
javadba

1
Meskipun kode Anda dapat dikoreksi sebagai jawaban. Tetapi menguraikan apa yang dikerjakan kode Anda, itu dapat meningkatkan kualitas jawaban Anda. Periksa Artikel: Bagaimana saya menulis jawaban yang bagus?
LuFFy

1

Selain balasan sebelumnya, saya ingin memperkenalkan fungsi lain.

numpy.random.shuffleserta random.shufflemelakukan pengocokan di tempat. Namun, jika Anda ingin mengembalikan array yang dikocok numpy.random.permutationadalah fungsi yang digunakan.


1

Saya tidak tahu saya menggunakan random.shuffle()tetapi mengembalikan 'Tidak ada' kepada saya, jadi saya menulis ini, mungkin membantu seseorang

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
ya itu mengembalikan Tidak ada, tetapi array diubah, jika Anda benar-benar ingin mengembalikan sesuatu maka lakukan impor acak ini shuffle def (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]

0

Sadarilah bahwa random.shuffle()tidak boleh digunakan pada array multi-dimensi karena menyebabkan pengulangan.

Bayangkan Anda ingin mengocok array di sepanjang dimensi pertama, kita dapat membuat contoh pengujian berikut,

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

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

sehingga sepanjang sumbu pertama, elemen ke-i sesuai dengan matriks 2x3 di mana semua elemen sama dengan i.

Jika kita menggunakan fungsi shuffle yang benar untuk array multi-dimensi, yaitu np.random.shuffle(x)array akan dikocok sepanjang sumbu pertama seperti yang diinginkan. Namun, menggunakan random.shuffle(x)akan menyebabkan pengulangan. Anda dapat memeriksa ini dengan menjalankan len(np.unique(x))setelah pengocokan yang memberi Anda 10 (seperti yang diharapkan) dengan np.random.shuffle()tetapi hanya sekitar 5 saat menggunakan random.shuffle().

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.