สลับสองรายการพร้อมกันด้วยลำดับเดียวกัน


94

ฉันใช้คลังข้อมูลnltkของห้องสมุดmovie_reviewsซึ่งมีเอกสารจำนวนมาก งานของฉันคือรับประสิทธิภาพเชิงคาดการณ์ของบทวิจารณ์เหล่านี้ด้วยการประมวลผลข้อมูลล่วงหน้าและไม่มีการประมวลผลล่วงหน้า แต่มีปัญหาในรายการdocumentsและdocuments2ฉันมีเอกสารเดียวกันและฉันต้องการสับเปลี่ยนเพื่อให้ลำดับเดียวกันในทั้งสองรายการ ฉันไม่สามารถสับเปลี่ยนแยกกันได้เพราะทุกครั้งที่ฉันสับเปลี่ยนรายการฉันจะได้ผลลัพธ์อื่น ๆ นั่นคือเหตุผลที่ฉันต้องสับในครั้งเดียวด้วยลำดับเดียวกันเพราะฉันต้องการเปรียบเทียบในตอนท้าย (ขึ้นอยู่กับลำดับ) ฉันใช้ python 2.7

ตัวอย่าง (ในความเป็นจริงเป็นโทเค็นสตริง แต่ไม่สัมพันธ์กัน):

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')]

และฉันต้องการผลลัพธ์นี้หลังจากสุ่มทั้งสองรายการ:

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')]

ฉันมีรหัสนี้:

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

คำตอบ:


230

คุณสามารถทำได้โดย:

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]

แน่นอนว่านี่เป็นตัวอย่างที่มีรายการที่ง่ายกว่า แต่การปรับเปลี่ยนจะเหมือนกันสำหรับกรณีของคุณ

หวังว่าจะช่วยได้ โชคดี.


ขอบคุณนั่นคือสิ่งที่ฉันต้องการ
Jaroslav Klimčík

5
(noob question) - * หมายถึงอะไร?
ᔕᖺᘎᕊ

2
@ ᔕᖺᘎᕊหมายถึงแกะค่าของ c จึงเรียกzip(1,2,3)แทนzip([1,2,3])
sshashank124

2
ฉันใช้วิธีนี้มาก่อนaและbเป็นรายการในตอนท้าย ด้วย Python 3.6.8 ในตอนท้ายของตัวอย่างเดียวกันฉันได้รับaและbเป็น tuples
vinzee

1
... Tuples ... ดังนั้นแค่ a = list (a) และ b = list (b)
RichardBJ

40

ฉันได้รับวิธีง่ายๆในการทำสิ่งนี้

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])

โพสต์ต้นฉบับเกี่ยวกับรายการปกติใน python แต่ฉันต้องการวิธีแก้ปัญหาสำหรับอาร์เรย์ numpy คุณเพิ่งช่วยวันของฉัน!
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]

6

สลับจำนวนรายการโดยอนุญาโตตุลาการพร้อมกัน

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)

เอาท์พุต:

$ (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)

หมายเหตุ:
วัตถุกลับโดยมีshuffle_list()tuples

ปล. shuffle_list()ยังสามารถนำไปใช้กับnumpy.array()

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

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

เอาท์พุต:

$ (3, 1, 2) (6, 4, 5)

4

วิธีที่ง่ายและรวดเร็วในการทำเช่นนี้คือการใช้ random.seed () กับ random.shuffle () ช่วยให้คุณสร้างคำสั่งสุ่มเดียวกันหลายครั้งที่คุณต้องการ จะมีลักษณะดังนี้:

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]

นอกจากนี้ยังใช้งานได้เมื่อคุณไม่สามารถทำงานกับทั้งสองรายการพร้อมกันได้เนื่องจากปัญหาหน่วยความจำ


2
ไม่ควรสุ่ม shuffle (a)?
Khan

-2

คุณสามารถใช้อาร์กิวเมนต์ที่สองของฟังก์ชันการสุ่มเพื่อแก้ไขลำดับของการสับเปลี่ยน

โดยเฉพาะคุณสามารถส่งผ่านอาร์กิวเมนต์ที่สองของฟังก์ชันสับเปลี่ยนฟังก์ชันอาร์กิวเมนต์เป็นศูนย์ซึ่งส่งคืนค่าเป็น [0, 1) ค่าส่งกลับของฟังก์ชันนี้จะแก้ไขลำดับของการสับ (โดยค่าเริ่มต้นคือถ้าคุณไม่ส่งฟังก์ชันใด ๆ เป็นอาร์กิวเมนต์ที่สองจะใช้ฟังก์ชันrandom.random()นี้คุณสามารถดูได้ที่บรรทัด 277 ที่นี่ )

ตัวอย่างนี้แสดงให้เห็นถึงสิ่งที่ฉันอธิบาย:

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

เอาท์พุต:

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

random.shuffleฟังก์ชั่นเรียกrandomฟังก์ชั่นมากกว่าหนึ่งครั้งเพื่อให้ใช้lambdaที่มักจะส่งกลับค่าเดียวกันอาจมีผลกระทบที่ไม่ได้ตั้งใจในการสั่งซื้อการส่งออก
Blckknght

คุณพูดถูก นี่จะเป็นการสับแบบเอนเอียงขึ้นอยู่กับค่าของ r มันอาจจะดีในหลาย ๆ กรณี แต่ก็ไม่เสมอไป
Kundan Kumar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.