2012-08-01 33 views
22

Có cách nào tốt hơn để ngẫu nhiên trộn hai danh sách có liên quan mà không vi phạm thư của chúng trong danh sách khác không? Tôi đã tìm thấy các câu hỏi có liên quan trong số numpy.arrayc# nhưng không giống chính xác câu hỏi đó.Cách tốt hơn để trộn hai danh sách liên quan

Là một thử đầu tiên, một zip lừa đơn giản sẽ làm:

import random 
a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] 
b = [2, 4, 6, 8, 10] 
c = zip(a, b) 
random.shuffle(c) 
a = [e[0] for e in c] 
b = [e[1] for e in c] 
print a 
print b 

Nó sẽ nhận được kết quả:

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

Chỉ cần tìm thấy nó một chút vụng về. Và nó cũng cần một danh sách bổ sung.

+5

bạn có thể sử dụng 'zip' để giải nén danh sách cũng:' a, b = zip (* c) ' – mgilson

+3

Tôi cũng thường không đề nghị một chương trình thiết kế nơi bạn cần giữ một tập hợp các danh sách song song. Chỉ cần giữ 1 danh sách. Tạo một số loại lớp học hoặc một cái gì đó để thống nhất dữ liệu của bạn. – mgilson

+0

Nếu một người muốn thực hiện công việc đó bằng 'numpy', đây là một giải pháp tốt: http: //stackoverflow.com/questions/4601373/better-way-to-shuffle-two-numpy-arrays-in-unison – Mithril

Trả lời

35

Với mối quan hệ được minh họa trong câu hỏi, tôi sẽ giả định danh sách có cùng độ dài và list1[i] tương ứng với list2[i] cho bất kỳ chỉ mục nào i. Với giả định rằng tại chỗ, xáo trộn danh sách đơn giản như xáo trộn các chỉ số:

from random import shuffle 
# Given list1 and list2 
list1_shuf = [] 
list2_shuf = [] 
index_shuf = range(len(list1)) 
shuffle(index_shuf) 
for i in index_shuf: 
    list1_shuf.append(list1[i]) 
    list2_shuf.append(list2[i]) 
+9

Như một fan hâm mộ của danh sách comprehensions: list1_shuf = [list1 [i] cho i trong index_shuf] –

+1

@kojiro: không quan trọng: n * append_ops + n * append_ops = n * (append_ops + append_ops) = 2 * n * append_ops – Lazik

5

Nếu bạn phải làm điều này thường xuyên, bạn có thể cân nhắc việc thêm một mức gián tiếp bằng cách xáo trộn một danh sách các chỉ mục.

Python 2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)] on 
win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import random 
>>> a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] 
>>> b = [2, 4, 6, 8, 10] 
>>> indexes = range(len(a)) 
>>> indexes 
[0, 1, 2, 3, 4] 
>>> random.shuffle(indexes) 
>>> indexes 
[4, 1, 2, 0, 3] 
>>> for index in indexes: 
...  print a[index], b[index] 
... 
[9, 10] 10 
[3, 4] 4 
[5, 6] 6 
[1, 2] 2 
[7, 8] 8 
0

Tôi không chắc là mình đang thiếu thứ gì ở đây, nhưng có vẻ như bạn đang xáo trộn 1 danh sách và danh sách kia được sắp xếp lại để khớp với thứ tự của danh sách đầu tiên. Vì vậy, những gì bạn có là cách tốt nhất để làm điều này mà không làm cho nó phức tạp hơn. Nếu bạn muốn đi các tuyến đường phức tạp, bạn chỉ có thể xáo trộn 1 danh sách và sử dụng danh sách unshuffled để làm một tra cứu trong danh sách xáo trộn và sắp xếp lại nó theo cách đó. Cuối cùng, bạn kết thúc với cùng một kết quả mà bạn đã bắt đầu. Tại sao tạo danh sách thứ ba là một vấn đề? Nếu bạn thực sự muốn tái chế các danh sách thì bạn có thể chỉ cần thay thế danh sách b bằng những gì bạn đang sử dụng cho danh sách c và sau đó tách nó ra sau về a và b.

1

Một câu trả lời nhanh chóng sử dụng NumPy vui lòng tham khảo here:
Bạn có thể sử dụng

p = numpy.random.permutation(len(a)) 

Để tạo một danh sách mới các chỉ số cho cả hai danh sách và sử dụng nó để sắp xếp lại chúng.

Trong kịch bản của bạn:

In [61]: a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] 
In [62]: b = [2, 4, 6, 8, 10] 
In [63]: import numpy as np 
In [64]: a_ar, b_ar = np.array(a), np.array(b) 
In [65]: p = np.random.permutation(len(a)) 
In [66]: a, b = a_ar[p].tolist(), b_ar[p].tolist() 
In [68]: a 
Out[68]: [[3, 4], [7, 8], [5, 6], [1, 2], [9, 10]] 
In [69]: b 
Out[69]: [4, 8, 6, 2, 10] 
14

Nếu bạn sẵn sàng để cài đặt thêm vài gói:

Req: NumPy (> = 1.6.1), scipy (> = 0,9).

pips cài đặt -U scikit-học

from sklearn.utils import shuffle 
list_1, list_2 = shuffle(list_1, list_2) 
Các vấn đề liên quan