Mische zwei Listen gleichzeitig mit derselben Reihenfolge

86

Ich benutze den Korpus der nltkBibliothek, movie_reviewsder eine große Anzahl von Dokumenten enthält. Meine Aufgabe ist es, eine vorausschauende Leistung dieser Überprüfungen mit Vorverarbeitung der Daten und ohne Vorverarbeitung zu erzielen. Aber es gibt ein Problem in Listen documentsund documents2ich habe die gleichen Dokumente und ich muss sie mischen, um die gleiche Reihenfolge in beiden Listen beizubehalten. Ich kann sie nicht separat mischen, da ich jedes Mal, wenn ich die Liste mische, andere Ergebnisse erhalte. Deshalb muss ich die auf einmal mit derselben Reihenfolge mischen, weil ich sie am Ende vergleichen muss (es hängt von der Reihenfolge ab). Ich benutze Python 2.7

Beispiel (in Wirklichkeit sind Zeichenfolgen mit Token versehen, aber nicht relativ):

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

Und ich muss dieses Ergebnis erhalten, nachdem ich beide Listen gemischt habe:

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

Ich habe diesen Code:

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
Jaroslav Klimčík
quelle
1
Mögliches Duplikat von Besserer Weg, um zwei numpy Arrays im Einklang zu mischen
Rick Smith

Antworten:

206

Sie können es tun als:

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]

Dies war natürlich ein Beispiel mit einfacheren Listen, aber die Anpassung ist für Ihren Fall dieselbe.

Ich hoffe es hilft. Viel Glück.

sshashank124
quelle
Danke, genau das brauche ich.
Jaroslav Klimčík
4
(noob frage) - was bedeutet das *?
2.
2
@ ᔕᖺᘎᕊ, Es bedeutet, die Werte von c zu entpacken, so dass es als zip(1,2,3)anstelle vonzip([1,2,3])
sshashank124
2
Ich habe diese Lösung vorher verwendet aund bwar am Ende eine Liste. Mit Python 3.6.8 bekomme ich am Ende desselben Beispiels aund bals Tupel.
Vinzee
1
... Tupel ... also nur a = Liste (a) und b = Liste (b)
RichardBJ
34

Ich bekomme einen einfachen Weg, dies zu tun

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])
hua wei
quelle
Der ursprüngliche Beitrag handelt von normalen Listen in Python, aber ich brauchte eine Lösung für Numpy-Arrays. Du hast gerade meinen Tag gerettet!
Finngu
6
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]
YScharf
quelle
5

Mische eine beliebige Anzahl von Listen gleichzeitig.

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)

Ausgabe:

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

Hinweis: Von zurückgegebene
Objekte shuffle_list()sind tuples.

PS shuffle_list()kann auch angewendet werdennumpy.array()

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

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

Ausgabe:

$ (3, 1, 2) (6, 4, 5)
Löwe Lai
quelle
4

Eine einfache und schnelle Möglichkeit, dies zu tun, besteht darin, random.seed () mit random.shuffle () zu verwenden. Sie können dieselbe zufällige Reihenfolge so oft generieren, wie Sie möchten. Es wird so aussehen:

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]

Dies funktioniert auch, wenn Sie aufgrund von Speicherproblemen nicht mit beiden Listen gleichzeitig arbeiten können.

Boris
quelle
1
sollte es nicht random.shuffle (a) sein?
Khan
-2

Sie können das zweite Argument der Shuffle-Funktion verwenden, um die Reihenfolge des Shufflings festzulegen.

Insbesondere können Sie dem zweiten Argument der Shuffle-Funktion eine Null-Argument-Funktion übergeben, die einen Wert in [0, 1) zurückgibt. Der Rückgabewert dieser Funktion legt die Reihenfolge des Mischens fest. (Standardmäßig wird die Funktion verwendet, wenn Sie keine Funktion als zweites Argument übergeben random.random(). Sie können sie in Zeile 277 hier sehen .)

Dieses Beispiel zeigt, was ich beschrieben habe:

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

Ausgabe:

['e', 'c', 'd', 'a', 'b']
[5, 3, 4, 1, 2]
Kundan Kumar
quelle
Die random.shuffleFunktion ruft die randomFunktion mehrmals auf, sodass die Verwendung von a lambda, die immer denselben Wert zurückgibt, unbeabsichtigte Auswirkungen auf die Ausgabereihenfolge haben kann.
Blckknght
Du hast recht. Dies ist ein vorgespanntes Mischen, abhängig vom Wert von r. Es kann in vielen Fällen praktisch gut sein, aber nicht immer.
Kundan Kumar