2014-04-25 168 views
29

我正在使用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 

回答

57

你可以做到這一點是:

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] 

當然,這是一個簡單列表的例子,但適應情況與您的情況相同。

希望它有幫助。祝你好運。

+0

@thefourtheye,太謝謝你了!我已經更新了我的答案。 – sshashank124

+0

謝謝,那正是我需要的。 –

+0

(noob問題) - *表示什麼? –

-4

您可以使用shuffle函數的第二個參數來修正混洗的順序。

具體來說,你可以傳遞shuffle函數的第二個參數一個零參數函數,它返回[0,1]中的一個值。這個函數的返回值修改了混洗的順序。 (默認情況下,如果你不傳遞任何函數作爲第二個參數,即,它採用了功能random.random()您可以在線路277 here看到它。)

這個例子說明了什麼我描述:

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] 
+0

'random.shuffle'函數不止一次調用'random'函數,所以使用總是返回相同值的'lambda'可能會對輸出順序產生意想不到的影響。 – Blckknght

+0

你說得對。這將是一個有偏見的洗牌,取決於r的價值。對許多情況來說它可能實際上很好,但並非總是如此。 –

3

同時將任意數量的列表隨機混洗。

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

P.S. 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) 
相關問題