2015-07-10 95 views
3

我想讀和處理大量的CSV文件(data_file),其具有下面的2柱結構:大熊貓:處理一個數據幀具有大量串

id params 
1 '14':'blah blah','25':'more cool stuff' 
2 '157':'yes, more stuff','15':'and even more' 
3 '14':'blah blah','25':'more cool stuff' 
4 '15':'different here' 
5 '157':'yes, more stuff','15':'and even more' 
6 '100':'exhausted' 

該文件包含30.000.000線(磁盤上5 Gb)。 (實際的字符串以UTF-8編碼;爲了簡單起見,我在這裏給出了他們的ASCII碼)。請注意,第二列中的一些值會重複。

我閱讀此使用pandas.read_csv()

df = pandas.read_csv(open(data_file, 'rb'), delimiter='\t', 
     usecols=['id', 'params'],dtype={'id':'u4', 'params':'str'}) 

一旦文件被讀取時,數據幀df使用的RAM 1.2 GB。

到目前爲止這麼好。

現在來處理部分。我想有這個格式,params字符串列:

blah blah||more cool stuff 
yes, more stuff||and even more 
blah blah||more cool stuff 
different here 
yes, more stuff||and even more 
exhausted 

我寫道:

def clean_keywords(x): 
    return "||".join(x.split("'")[1:][::2]) 

df['params'] = df['params'].map(clean_keywords) 

此代碼工作在這個意義上它給出正確的結果。但是:

  1. 執行map操作時使用的RAM超過6.8 Gb。
  2. 計算完成後,儘管在params列中計算的字符串比讀取的字符串短,但使用了5.5 Gb的RAM df(在gc.collect()之後)。

有人可以解釋這一點,並提出一種使用熊貓來執行上述操作的替代方法(我使用python 3.4,pandas 0.16.2,win64)?

+0

你的代碼產生這樣的:'缺貨[69]: ID PARAMS 0 1 14 ||等等等等|| || 25更涼爽的東西 1 2 157 ||是,更多的東西|| || 15乃至str.split(「'」)。str [1:]。str [:: 2] .str.join('||')' – EdChum

+0

@EdChum,我簡化了我實際編寫的原始代碼。也許我犯了一個錯誤?我沒有得到你想告訴我的。你的代碼更有效率?我剛剛試過你的代碼:RAM超過7 GB。 –

+0

這也許因爲這是矢量化'str'方法也許值得嘗試修改代碼以使用類似於我建議的代碼,這可能不是解決你的記憶問題,雖然 – EdChum

回答

2

回答我自己的問題。

事實證明,pandas.read_csv()是聰明的。讀取文件時,字符串是唯一的。但是,當這些字符串被處理並存儲在列中時,它們不再是唯一的。因此RAM使用率增加。爲了避免這種情況,必須手動維護唯一性。我這樣做:

unique_strings = {} 

def clean_keywords(x): 
    s = "||".join(x.split("'")[1:][::2]) 
    return unique_strings.setdefault(s, s) 

df['params'] = df['params'].map(clean_keywords) 

有了這種解決方案,RAM最大。正如預期的那樣,在讀取數據(1.2 Gb)後,在最初的RAM使用情況下,使用量僅爲2.8 Gb,並略有下降。

+0

這似乎是一個有用的技術知道。 –