2017-03-29 41 views
2

我收集了一些我想分解成文字的文檔。這是一個例子集合:熊貓的split/stack combo是否有效實施?

In [1]: 
import pandas as pd 
docs = pd.DataFrame({'docno' : ['doc1', 'doc2'], 'doc' : ['to be or not to be', 'that is the question']}) 
docs 

Out[1]: 
    doc     docno 
0 to be or not to be doc1 
1 that is the question doc2 

我找不到一個直接的方式來上面的「展開」每一行成一系列如下行,但已經看到,這是與tolist()完成的,然後堆():

In [2]: 
terms = pd.DataFrame(docs.doc.str.split().tolist(), index=docs.docno).stack() 
terms = terms.reset_index()[[0, 'docno']] 
terms.columns = ['term', 'docno'] 
terms 

Out[2]: 
    term  docno 
0 to  doc1 
1 be  doc1 
2 or  doc1 
3 not  doc1 
4 to  doc1 
5 be  doc1 
6 that  doc2 
7 is  doc2 
8 the  doc2 
9 question doc2 

我懷疑是不是最優化的,使得堆疊在結合完成,而是N個維度(其中N是詞彙的大小)的中間表被用於分割寫入( ),然後再堆疊。文檔可能非常大,整個文檔集合中的詞彙也是如此。所以這似乎相當低效。 我目前正在對〜5GB集合進行這種轉換,目前使用的是大約2.5TB的RAM(到目前爲止);這似乎證實了我懷疑分割/堆棧操作實際上是串聯的。

我的問題是:有沒有更好的方法來做到這一點?

+0

(1)非常嫉妒你的RAM 2.5TB到(2)當你有內存問題時,總是應該考慮迭代器。你有沒有試圖爲此開發一個迭代算法? –

回答

0

我認爲你可以使用numpy solution - 第一splitdocs,然後str.lenlists GET長度由numpy.repeatflattening lists重複:

from itertools import chain 

docs.doc = docs.doc.str.split() 
df1 = pd.DataFrame({ 
     "docno": np.repeat(docs.docno.values, docs.doc.str.len()), 
     "term": list(chain.from_iterable(docs.doc))})[['term','docno']] 

print (df1) 
     term docno 
0  to doc1 
1  be doc1 
2  or doc1 
3  not doc1 
4  to doc1 
5  be doc1 
6  that doc2 
7  is doc2 
8  the doc2 
9 question doc2 
+0

感謝堆 - 似乎正是我想要的! – bop