2つのリストを同じ順序で一度にシャッフルします


88

多数のドキュメントを含むnltkライブラリのmovie_reviewsコーパスを使用しています。私の仕事は、データの前処理を行い、前処理を行わずに、これらのレビューの予測パフォーマンスを取得することです。しかし、リストに、問題があるdocumentsdocuments2私は同じ文書を持っていると私は両方のリストに同じ順序を維持するためにそれらをシャッフルする必要が。リストをシャッフルするたびに他の結果が得られるため、個別にシャッフルすることはできません。そのため、最終的に比較する必要があるため、同じ順序で一度にシャッフルする必要があります(順序によって異なります)。私はPython2.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

回答:


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]

もちろん、これはより単純なリストの例でしたが、適応はあなたの場合と同じです。

それが役に立てば幸い。幸運を。


おかげで、それはまさに私が必要なものです。
ヤロスラフKlimčík

4
(noob質問)-*はどういう意味ですか?
ᔕᖺᘎᕊ

2
@ᔕᖺᘎᕊ、cの値を解凍して、zip(1,2,3)代わりに呼び出されることを意味しますzip([1,2,3])
sshashank124 2015

2
私は前にこのソリューションを使用し、aそしてb最後にリストしました。Pythonの3.6.8では、同じ例の最後に、私が取得aし、bタプルなど。
vinzee

1
...タプル...ので、ちょうど=リスト()とb =リスト(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
ランダムであってはなりません。shuffle(a)?
カーン

-2

シャッフル関数の2番目の引数を使用して、シャッフルの順序を修正できます。

具体的には、シャッフル関数の2番目の引数に、[0、1)の値を返すゼロ引数関数を渡すことができます。この関数の戻り値は、シャッフルの順序を修正します。(デフォルトでは、つまり、2番目の引数として関数を渡さない場合、関数が使用されます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 2016年

あなたが正しいです。これは、rの値に応じて、偏ったシャッフルになります。多くの場合、それは実際には良いかもしれませんが、常にではありません。
Kundan Kumar 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.