동일한 순서로 한 번에 두 목록을 섞습니다.


88

많은 문서가 포함 된 nltk도서관의 movie_reviews코퍼스를 사용하고 있습니다 . 내 임무는 데이터를 사전 처리하고 사전 처리하지 않고 이러한 리뷰의 예측 성능을 얻는 것입니다. 그러나 목록에, 문제가 documentsdocuments2나는 같은 문서가 나는 두 목록에 같은 순서를 유지하기 위해 그들을 셔플 필요가있다. 목록을 섞을 때마다 다른 결과가 나오기 때문에 따로 섞을 수 없습니다. 그래서 결국 비교가 필요하기 때문에 (순서에 따라 다름) 같은 순서로 한 번에 섞어 야합니다. 파이썬 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

답변:


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]

물론 이것은 더 간단한 목록의 예이지만 귀하의 경우에 대한 적응은 동일합니다.

도움이 되었기를 바랍니다. 행운을 빕니다.


고마워요, 그게 바로 제가 필요한 것입니다.
Jaroslav Klimčík 2014

4
(noob question)-*는 무엇을 의미합니까?
ᔕᖺᘎᕊ 2015-04-02

2
이이라되도록 @ ᔕᖺᘎᕊ, 그것은 C의 값을 압축하는 수단 zip(1,2,3)이 아닌zip([1,2,3])
sshashank124

2
나는 전에이 솔루션을 사용 a하고 b마지막에 목록을했다. 파이썬 3.6.8로, 같은 예제의 끝에서, 나는 얻을 ab튜플있다.
vinzee 19

1
... 튜플 ... 그래서 그냥 = 목록의 (a)와 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])

원래 게시물은 파이썬의 일반 목록에 관한 것이지만 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.shuffle ()과 함께 random.seed ()를 사용하는 것입니다. 원하는 여러 번 동일한 임의 순서를 생성 할 수 있습니다. 다음과 같이 표시됩니다.

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)이어야합니까?
Khan

-2

셔플 함수의 두 번째 인수를 사용하여 셔플 링 순서를 수정할 수 있습니다.

특히, shuffle 함수의 두 번째 인수에 [0, 1)의 값을 반환하는 0 인수 함수를 전달할 수 있습니다. 이 함수의 반환 값은 셔플 링 순서를 수정합니다. (기본적으로 즉, 두 번째 인수로 어떤 함수도 전달하지 않으면 함수를 사용합니다 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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.