2014-12-06 30 views
3

我的第一篇文章:Python的 - 降低進口和分析時大CSV文件

在開始之前,我要說明我是比較新的面向對象,雖然我已經在SAS,R等做DB /統計工作,所以我的問題可能不會很好地提出:請讓我知道我是否需要澄清任何事情。

我的問題:

我試圖導入並解析大CSV文件(〜6MM行和更大的可能來)。我重複運行的兩個限制是運行時和內存(Python的32位實現)。下面是我的初學者(第n次)在合理時間內導入和解析的嘗試的簡化版本。 如何加快此過程?我分裂文件,我導入和執行臨時摘要由於內存限制,並使用熊貓的總結:

解析和總結:

def ParseInts(inString): 
    try: 
     return int(inString) 
    except: 
     return None 
def TextToYearMo(inString): 
    try: 
     return 100*inString[0:4]+int(inString[5:7]) 
    except: 
     return 100*inString[0:4]+int(inString[5:6]) 
def ParseAllElements(elmValue,elmPos): 
    if elmPos in [0,2,5]: 
     return elmValue 
    elif elmPos == 3: 
     return TextToYearMo(elmValue) 
    else: 
     if elmPos == 18: 
      return ParseInts(elmValue.strip('\n')) 
     else: 
      return ParseInts(elmValue) 

def MakeAndSumList(inList): 
    df = pd.DataFrame(inList, columns = ['x1','x2','x3','x4','x5', 
             'x6','x7','x8','x9','x10', 
             'x11','x12','x13','x14']) 
    return df[['x1','x2','x3','x4','x5', 
       'x6','x7','x8','x9','x10', 
       'x11','x12','x13','x14']].groupby(
       ['x1','x2','x3','x4','x5']).sum().reset_index() 

函數調用:

def ParsedSummary(longString,delimtr,rowNum): 
    keepColumns = [0,3,2,5,10,9,11,12,13,14,15,16,17,18] 

    #Do some other stuff that takes very little time 

    return [pse.ParseAllElements(longString.split(delimtr)[i],i) for i in keepColumns] 

def CSVToList(fileName, delimtr=','): 
    with open(fileName) as f: 
     enumFile = enumerate(f) 
     listEnumFile = set(enumFile) 
     for lineCount, l in enumFile: 
      pass 

     maxSplit = math.floor(lineCount/10) + 1 

     counter = 0 
     Summary = pd.DataFrame({}, columns = ['x1','x2','x3','x4','x5', 
               'x6','x7','x8','x9','x10', 
               'x11','x12','x13','x14']) 
     for counter in range(0,10): 
      startRow  = int(counter * maxSplit) 
      endRow  = int((counter + 1) * maxSplit) 
      includedRows = set(range(startRow,endRow)) 

      listOfRows = [ParsedSummary(row,delimtr,rownum) 
          for rownum, row in listEnumFile if rownum in includedRows] 
      Summary = pd.concat([Summary,pse.MakeAndSumList(listOfRows)]) 

      listOfRows = [] 
      counter += 1 
    return Summary 

(再一次,這是我的第一個問題 - 所以我很抱歉,如果我簡化得太多,或者更可能太少,但我不知道如何加快這一點。)

對於運行時間比較:

使用訪問我可以導入,分析,總結,在這個尺寸範圍在< 5分鐘合併幾個文件(雖然我在它的2GB LIM是正確的)。我希望我能在Python中獲得類似的結果 - 目前我估計一個文件的運行時間約爲30分鐘。注意:我在Access的悲慘環境中一起投擲了一些東西,只是因爲我沒有管理員權限隨時可以安裝其他任何東西。

編輯:更新解析代碼。能夠通過改變一些條件邏輯來嘗試/除了5分鐘(在25m的運行時間)。另外 - 運行時估算不包括大熊貓的部分 - 我忘記了我在測試時評論過,但其影響似乎可以忽略不計。

+0

這不是python選項。但是你有沒有考慮過R中的data.table包? – jazzurro 2014-12-06 03:17:14

+0

我沒有。這對我來說是一個宕機項目 - 我想創建一個可執行的後處理程序。比處理我們的模擬輸出。也就是說,這不需要我們的其他預測者在他們的計算機上安裝任何其他軟件。出於安全原因,我們的環境非常有限。 – riemannh 2014-12-06 04:12:50

+0

[在python中讀取一個巨大的.csv文件](http://stackoverflow.com/questions/17444679/reading-a-huge-csv-in-python) – 2014-12-06 18:16:52

回答

1

如果您想優化性能,請不要在Python中使用您自己的CSV閱讀器。已經有一個標準csv模塊。也許pandasnumpy有更快的CSV閱讀器;我不確定。

https://softwarerecs.stackexchange.com/questions/7463/fastest-python-library-to-read-a-csv-file

總之,pandas.io.parsers.read_csv擊敗其他人,與NumPy的loadtxt赫然緩慢,與NumPy的from_fileload赫然快。

+0

登錄時遇到問題,但我記得在嘗試此操作時我使用了parse_dates = 3 - 我將在沒有此操作的情況下重試,並嘗試使用上面的函數(導入後)解析。 – riemannh 2014-12-06 19:53:36

+0

我再次嘗試這種導入方法 - parse_dates似乎導致問題。使用這種方法導入看起來非常快速,只要我使用上面的Text to YearMo函數(導入後),我可以根據需要在合理的時間解析日期。我將不得不挖掘並瞭解熊貓如何編寫導入函數,以及爲什麼它沒有其他方法似乎存在的內存問題(如果我理解它)來理解我做錯了什麼。謝謝你提示我重新訪問這個方法! – riemannh 2014-12-06 20:20:25