Aynı sırayla iki listeyi aynı anda karıştırın


94

Çok sayıda belge içeren nltkkütüphanenin movie_reviewskülliyatını kullanıyorum . Benim görevim, verilerin önceden işlenmesiyle ve ön işlem yapılmadan bu incelemelerin tahmini performansını elde etmektir. Ama listelerde, sorun var documentsve documents2ben aynı dokümanları var ve her iki listede de aynı düzeni sağlamak için bunları karıştırmak gerekmez. Bunları ayrı ayrı karıştıramıyorum çünkü listeyi her karıştırdığımda başka sonuçlar alıyorum. Bu yüzden aynı sırayla karıştırmam gerekiyor çünkü sonunda onları karşılaştırmam gerekiyor (sıraya bağlı). Python 2.7 kullanıyorum

Örnek (gerçekte dizeler belirtilmiştir, ancak göreli değildir):

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

Ve her iki listeyi karıştırdıktan sonra bu sonucu almam gerekiyor:

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

Bu koda sahibim:

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

Yanıtlar:


230

Bunu şu şekilde yapabilirsiniz:

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]

Elbette bu daha basit listeleri olan bir örnekti, ancak sizin durumunuz için uyarlama aynı olacaktır.

Umarım yardımcı olur. İyi şanslar.


Teşekkürler, tam da ihtiyacım olan şey bu.
Jaroslav Klimčík

5
(çaylak soru) - * ne anlama geliyor?
ᔕᖺᘎᕊ

2
@ ᔕᖺᘎᕊ, c'nin değerlerini paketten çıkarmak anlamına gelir, böylece zip(1,2,3)yerinezip([1,2,3])
sshashank124

2
Bu çözümü daha önce kullandım ave bsonunda listeler vardı. Python 3.6.8 ile aynı örnekte sonunda, benim hemen ave bküpe olarak.
vinzee

1
... Tuples ... yani sadece a = list (a) ve b = list (b)
RichardBJ

41

Bunu yapmanın kolay bir yolunu buluyorum

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

Orijinal gönderi python'daki normal listelerle ilgili, ancak uyuşuk diziler için bir çözüme ihtiyacım vardı. Günümü kurtardın!
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

Aynı anda birden fazla listeyi karıştırın.

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)

Çıktı:

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

Not: are
tarafından döndürülen nesneler .shuffle_list()tuples

PS shuffle_list()şunlara da uygulanabilirnumpy.array()

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

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

Çıktı:

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

4

Bunu yapmanın kolay ve hızlı yolu, random.seed () ile random.shuffle () kullanmaktır. İstediğiniz birçok kez aynı rastgele sırayı oluşturmanıza olanak tanır. Bunun gibi görünecek:

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]

Bu, bellek sorunları nedeniyle her iki listeyle aynı anda çalışamadığınızda da işe yarar.


2
random.shuffle (a) olmamalı mı?
Khan

-2

Karıştırma sırasını sabitlemek için karıştırma işlevinin ikinci bağımsız değişkenini kullanabilirsiniz.

Spesifik olarak, karıştırma işlevinin ikinci bağımsız değişkenine [0, 1) 'de bir değer döndüren bir sıfır bağımsız değişken işlevini iletebilirsiniz. Bu işlevin dönüş değeri, karıştırma sırasını düzeltir. (Varsayılan olarak, yani ikinci bağımsız değişken olarak herhangi bir işlevi iletmezseniz, işlevi kullanır random.random(). Burada 277. satırda görebilirsiniz .)

Bu örnek, anlattıklarımı göstermektedir:

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

Çıktı:

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

random.shuffleİşlevini çağırır randomböylece kullanılarak birden fazla kez işlevi lambdaher zaman aynı değere sonucu çıkış için üzerinde istenmeyen etkilere sahip olabilir.
Blckknght

Haklısın. Bu, r'nin değerine bağlı olarak önyargılı bir karıştırma olacaktır. Pek çok durumda pratik olarak iyi olabilir, ancak her zaman değil.
Kundan Kumar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.