一次以相同顺序随机播放两个列表


88

我正在使用包含大量文档的nltk图书馆movie_reviews语料库。我的任务是在没有数据预处理的情况下获得这些评论的预测性能。但是有一个问题,在列表中documentsdocuments2我有相同的文档,因此我需要对它们进行混洗,以便在两个列表中保持相同的顺序。我无法分别对它们进行洗牌,因为每次我对列表进行洗牌时,都会得到其他结果。这就是为什么我需要用相同的顺序立即将其洗牌,因为最后需要比较它们(取决于顺序)。我正在使用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

Answers:


216

您可以按照以下方式进行操作:

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]

当然,这是一个具有更简单列表的示例,但适应情况与您的情况相同。

希望能帮助到你。祝好运。


谢谢,这正是我所需要的。
JaroslavKlimčík2014年

4
(菜鸟问题)-*是什么意思?
ᔕᖺᘎᕊ

2
@ᔕᖺᘎᕊ,这意味着解压缩c的值,所以它被称为zip(1,2,3)而不是zip([1,2,3])
sshashank124

2
我用这个解决方案之前a,并b分别列出了底。在同一示例的最后,使用Python 3.6.8,我得到了aandb作为元组。
vinzee '19

1
...问题...所以只是a = list(a)和b = list(b)
RichardBJ

37

我有一个简单的方法来做到这一点

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

10
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

PS 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
它不应该是random.shuffle(a)吗?
可汗

-2

您可以使用随机播放功能的第二个参数来固定随机播放的顺序。

具体来说,您可以将shuffle函数的第二个参数传递给零参数函数,该函数返回[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始终返回相同值的a可能会对输出顺序产生意外影响。
Blckknght

你是对的。这将是有偏差的混洗,具体取决于r的值。在许多情况下,这实际上可能很好,但并非总是如此。
Kundan Kumar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.