Kocok dua daftar sekaligus dengan urutan yang sama

94

Saya menggunakan korpus nltkperpustakaan movie_reviewsyang berisi banyak dokumen. Tugas saya adalah mendapatkan kinerja prediksi dari tinjauan ini dengan pra-pemrosesan data dan tanpa pemrosesan awal. Tetapi ada masalah, dalam daftar documentsdan documents2saya memiliki dokumen yang sama dan saya perlu mengocoknya untuk menjaga urutan yang sama di kedua daftar. Saya tidak dapat mengocoknya secara terpisah karena setiap kali saya mengacak daftar, saya mendapatkan hasil lain. Itu sebabnya saya perlu mengocok sekaligus dengan urutan yang sama karena saya perlu membandingkannya pada akhirnya (tergantung pesanan). Saya menggunakan python 2.7

Contoh (sebenarnya adalah string yang diberi token, tetapi ini tidak relatif):

documents = [(['plot : two teen couples go to a church party , '], 'neg'),
             (['drink and then drive . '], 'pos'),
             (['they get into an accident . '], 'neg'),
             (['one of the guys dies'], 'neg')]

documents2 = [(['plot two teen couples church party'], 'neg'),
              (['drink then drive . '], 'pos'),
              (['they get accident . '], 'neg'),
              (['one guys dies'], 'neg')]

Dan saya perlu mendapatkan hasil ini setelah mengocok kedua daftar:

documents = [(['one of the guys dies'], 'neg'),
             (['they get into an accident . '], 'neg'),
             (['drink and then drive . '], 'pos'),
             (['plot : two teen couples go to a church party , '], 'neg')]

documents2 = [(['one guys dies'], 'neg'),
              (['they get accident . '], 'neg'),
              (['drink then drive . '], 'pos'),
              (['plot two teen couples church party'], 'neg')]

Saya memiliki kode ini:

def cleanDoc(doc):
    stopset = set(stopwords.words('english'))
    stemmer = nltk.PorterStemmer()
    clean = [token.lower() for token in doc if token.lower() not in stopset and len(token) > 2]
    final = [stemmer.stem(word) for word in clean]
    return final

documents = [(list(movie_reviews.words(fileid)), category)
             for category in movie_reviews.categories()
             for fileid in movie_reviews.fileids(category)]

documents2 = [(list(cleanDoc(movie_reviews.words(fileid))), category)
             for category in movie_reviews.categories()
             for fileid in movie_reviews.fileids(category)]

random.shuffle( and here shuffle documents and documents2 with same order) # or somehow
Jaroslav Klimčík
sumber

Jawaban:

230

Anda dapat melakukannya sebagai:

import random

a = ['a', 'b', 'c']
b = [1, 2, 3]

c = list(zip(a, b))

random.shuffle(c)

a, b = zip(*c)

print a
print b

[OUTPUT]
['a', 'c', 'b']
[1, 3, 2]

Tentu saja, ini adalah contoh dengan daftar yang lebih sederhana, tetapi adaptasinya akan sama untuk kasus Anda.

Semoga membantu. Semoga berhasil.

sshashank124
sumber
Terima kasih, itulah yang saya butuhkan.
Jaroslav Klimčík
5
(pertanyaan noob) - apa artinya *?
ᔕᖺᘎᕊ
2
@ ᔕᖺᘎᕊ, Ini berarti membongkar nilai-nilai c sehingga disebut sebagai zip(1,2,3)penggantizip([1,2,3])
sshashank124
2
Saya menggunakan solusi ini sebelumnya dan adan bdaftar di bagian akhir. Dengan Python 3.6.8, di akhir contoh yang sama, saya mendapatkan adan bsebagai tupel.
vinzee
1
... Tuple ... jadi hanya a = daftar (a) dan b = daftar (b)
RichardBJ
40

Saya mendapatkan cara mudah untuk melakukan ini

import numpy as np
a = np.array([0,1,2,3,4])
b = np.array([5,6,7,8,9])

indices = np.arange(a.shape[0])
np.random.shuffle(indices)

a = a[indices]
b = b[indices]
# a, array([3, 4, 1, 2, 0])
# b, array([8, 9, 6, 7, 5])
hua wei
sumber
Posting asli adalah tentang daftar normal dengan python, tetapi saya membutuhkan solusi untuk array numpy. Anda baru saja menyelamatkan hari saya!
finngu
11
from sklearn.utils import shuffle

a = ['a', 'b', 'c','d','e']
b = [1, 2, 3, 4, 5]

a_shuffled, b_shuffled = shuffle(np.array(a), np.array(b))
print(a_shuffled, b_shuffled)

#random output
#['e' 'c' 'b' 'd' 'a'] [5 3 2 4 1]
YScharf
sumber
6

Kocok daftar jumlah arbitrase secara bersamaan.

from random import shuffle

def shuffle_list(*ls):
  l =list(zip(*ls))

  shuffle(l)
  return zip(*l)

a = [0,1,2,3,4]
b = [5,6,7,8,9]

a1,b1 = shuffle_list(a,b)
print(a1,b1)

a = [0,1,2,3,4]
b = [5,6,7,8,9]
c = [10,11,12,13,14]
a1,b1,c1 = shuffle_list(a,b,c)
print(a1,b1,c1)

Keluaran:

$ (0, 2, 4, 3, 1) (5, 7, 9, 8, 6)
$ (4, 3, 0, 2, 1) (9, 8, 5, 7, 6) (14, 13, 10, 12, 11)

Catatan:
objek yang dikembalikan oleh shuffle_list()are tuples.

PS shuffle_list()juga bisa diterapkannumpy.array()

a = np.array([1,2,3])
b = np.array([4,5,6])

a1,b1 = shuffle_list(a,b)
print(a1,b1)

Keluaran:

$ (3, 1, 2) (6, 4, 5)
Lion Lai
sumber
4

Cara mudah dan cepat untuk melakukannya adalah dengan menggunakan random.seed () dengan random.shuffle (). Ini memungkinkan Anda menghasilkan urutan acak yang sama berkali-kali yang Anda inginkan. Ini akan terlihat seperti ini:

a = [1, 2, 3, 4, 5]
b = [6, 7, 8, 9, 10]
seed = random.random()
random.seed(seed)
a.shuffle()
random.seed(seed)
b.shuffle()
print(a)
print(b)

>>[3, 1, 4, 2, 5]
>>[8, 6, 9, 7, 10]

Ini juga berfungsi ketika Anda tidak dapat bekerja dengan kedua daftar pada saat yang sama, karena masalah memori.

Boris
sumber
2
bukankah seharusnya acak.shuffle (a)?
Khan
-2

Anda dapat menggunakan argumen kedua dari fungsi shuffle untuk memperbaiki urutan pengacakan.

Secara khusus, Anda bisa meneruskan argumen kedua dari fungsi shuffle sebagai fungsi argumen nol yang mengembalikan nilai dalam [0, 1). Nilai yang dikembalikan dari fungsi ini memperbaiki urutan pengacakan. (Secara default, yaitu jika Anda tidak meneruskan fungsi apa pun sebagai argumen kedua, argumen tersebut menggunakan fungsi tersebut random.random(). Anda dapat melihatnya di baris 277 di sini .)

Contoh ini menggambarkan apa yang saya jelaskan:

import random

a = ['a', 'b', 'c', 'd', 'e']
b = [1, 2, 3, 4, 5]

r = random.random()            # randomly generating a real in [0,1)
random.shuffle(a, lambda : r)  # lambda : r is an unary function which returns r
random.shuffle(b, lambda : r)  # using the same function as used in prev line so that shuffling order is same

print a
print b

Keluaran:

['e', 'c', 'd', 'a', 'b']
[5, 3, 4, 1, 2]
Kundan Kumar
sumber
The random.shufflefungsi panggilan randomfungsi lebih dari sekali, sehingga menggunakan lambdayang selalu mengembalikan nilai yang sama mungkin memiliki efek yang tidak diinginkan pada urutan output.
Blckknght
Kamu benar. Ini akan menjadi pengocokan yang bias, tergantung pada nilai r. Ini mungkin bagus untuk banyak kasus tetapi tidak selalu.
Kundan Kumar