2016-07-05 57 views
4

一個大的數據文件,我有一個比較大的(1 GB)的文本,我想在尺寸,以減少文件:如何流中,並通過跨類別總結操縱蟒蛇

Geography AgeGroup Gender Race Count 
County1 1  M  1 12 
County1 2  M  1 3 
County1 2  M  2 0 

要:

Geography Count 
County1 15 
County2 23 

這將是一件簡單的事情,如果整個文件可以適應內存,但使用pandas.read_csv()給出MemoryError。所以我一直在研究其他方法,看起來有很多選項 - HDF5?使用itertools(這看起來很複雜 - 生成器?)或者只是使用標準文件方法讀取第一個地理區域(70行),對count列進行求和,然後在另外70行加載之前寫出。

有沒有人有最好的方法來做到這一點的任何建議?我特別喜歡將數據流式傳輸的想法,特別是因爲我可以考慮很多其他可能有用的地方。我對這種方法最感興趣,或者同樣使用最基本的功能。

編輯:在這個小案例中,我只想要按地理位置計算的總和。但是,如果我可以讀取塊,指定任何函數(例如,一起添加2列,或按地理位置獲取列的最大值),應用函數並在讀入新塊之前寫入輸出,那麼這將是理想的。

+0

所以你不想在中間的3列? – ayhan

+0

我編輯了一個問題來澄清,謝謝 – HFBrowning

+2

你知道[大熊貓閱讀大全](http://pandas.pydata.org/pandas-docs/stable/io.html#iterating-through-files-chunk-by-塊)? 'Pd等。read_csv('myfile.csv',chunksize = 1000)'。然後你可以在一個循環內對零件進行操作。 – chrisaycock

回答

9

您可以使用dask.dataframe,這在語法上是相似pandas,但執行的操作外的核心,所以內存不應該是一個問題:

import dask.dataframe as dd 

df = dd.read_csv('my_file.csv') 
df = df.groupby('Geography')['Count'].sum().to_frame() 
df.to_csv('my_output.csv') 

另外,如果pandas是一個要求,你可以使用分塊讀取,如@chrisaycock所述。您可能想要試驗chunksize參數。

# Operate on chunks. 
data = [] 
for chunk in pd.read_csv('my_file.csv', chunksize=10**5): 
    chunk = chunk.groupby('Geography', as_index=False)['Count'].sum() 
    data.append(chunk) 

# Combine the chunked data. 
df = pd.concat(data, ignore_index=True) 
df = df.groupby('Geography')['Count'].sum().to_frame() 
df.to_csv('my_output.csv') 
2

我喜歡@根本的解決辦法,但我會去有點進一步優化內存使用情況 - 只保留聚集DF在內存中,僅讀取這些列,你真的需要:

cols = ['Geography','Count'] 
df = pd.DataFrame() 

chunksize = 2 # adjust it! for example --> 10**5 
for chunk in (pd.read_csv(filename, 
          usecols=cols, 
          chunksize=chunksize) 
      ): 
    # merge previously aggregated DF with a new portion of data and aggregate it again 
    df = (pd.concat([df, 
        chunk.groupby('Geography')['Count'].sum().to_frame()]) 
      .groupby(level=0)['Count'] 
      .sum() 
      .to_frame() 
     ) 

df.reset_index().to_csv('c:/temp/result.csv', index=False) 

測試數據:

Geography,AgeGroup,Gender,Race,Count 
County1,1,M,1,12 
County2,2,M,1,3 
County3,2,M,2,0 
County1,1,M,1,12 
County2,2,M,1,33 
County3,2,M,2,11 
County1,1,M,1,12 
County2,2,M,1,111 
County3,2,M,2,1111 
County5,1,M,1,12 
County6,2,M,1,33 
County7,2,M,2,11 
County5,1,M,1,12 
County8,2,M,1,111 
County9,2,M,2,1111 

output.csv:

Geography,Count 
County1,36 
County2,147 
County3,1122 
County5,24 
County6,33 
County7,11 
County8,111 
County9,1111 

使用此方法的PS可以處理大量文件。

PPS採用分塊方法應該工作,除非你需要理清你的數據 - 在這種情況下,我會用經典UNIX工具,如awksort等排序第一數據

我也建議使用PyTables(HDF5存儲),而不是CSV文件 - 它非常快速並允許您有條件地讀取數據(使用where參數),所以它非常方便並節省了大量資源,通常與CSV相比較爲much faster