2016-09-27 77 views
8

我有一個大的文件(2GB)的分類數據(主要是「南」 - 但實際值​​在這裏和那裏填充),這是太大,無法讀入一個單一的數據幀。我有一個相當困難的時候想出一個對象來存儲每列的所有唯一值(這是我的目標 - 最終我需要將這個因子分解爲建模)Pythonic的方式來增長列表

我最終做的是讀取文件以塊形式存儲到數據框中,然後獲取每列的唯一值並將它們存儲在列表中。我的解決方案很有效,但看起來最沒有pythonic - 是否有更簡潔的方式在Python中實現這一點(3.5版本)。我知道列數(〜2100)。

import pandas as pd 
#large file of csv separated text data 
data=pd.read_csv("./myratherlargefile.csv",chunksize=100000, dtype=str) 

collist=[] 
master=[] 
i=0 
initialize=0 
for chunk in data: 
    #so the first time through I have to make the "master" list 
    if initialize==0: 
     for col in chunk: 
      #thinking about this, i should have just dropped this col 
      if col=='Id': 
       continue 
      else: 
       #use pd.unique as a build in solution to get unique values 
       collist=chunk[col][chunk[col].notnull()].unique().tolist() 
       master.append(collist) 
       i=i+1 
    #but after first loop just append to the master-list at 
    #each master-list element 
    if initialize==1: 
     for col in chunk: 
      if col=='Id': 
       continue 
      else: 
       collist=chunk[col][chunk[col].notnull()].unique().tolist() 
       for item in collist: 
        master[i]=master[i]+collist 
       i=i+1 
    initialize=1 
    i=0 

在那之後,我對所有的獨特的價值觀最終任務如下:

i=0 
names=chunk.columns.tolist() 
for item in master: 
    master[i]=list(set(item)) 
    master[i]=master[i].append(names[i+1]) 
    i=i+1 

從而掌握[I]給我的列名,然後唯一值的列表 - 原油,但它確實有用 - 我主要關心的是如果可能的話,以「更好」的方式建立清單。

+0

您曾經考慮過使用一臺發電機懶洋洋地讀取文件? (查找yield關鍵字) – salparadise

+0

這可能會訣竅。我對迭代器和生成器不太瞭解 - 但按照建議粗略瀏覽一下yield關鍵字似乎是正確的。 – RDS

+0

這實際上是在引擎蓋下使用發電機。大塊大小就是這樣做的。出於好奇,你在32位或64位機器上運行/ python? 'import sys;打印(sys.maxsize)'應該工作,只要你正在運行python 2.6 –

回答

8

我會建議,而不是listlist s,使用collections.defaultdict(set)

假設您從

uniques = collections.defaultdict(set) 

現在環就這樣的事情:

for chunk in data: 
    for col in chunk: 
     uniques[col] = uniques[col].union(chunk[col].unique()) 

需要注意的是:

  1. defaultdict總是有setuniques[col](這是它在那裏),所以你可以跳過initialized和東西。

  2. 對於給定的col,只需使用當前集(最初爲空,但無關緊要)和新唯一元素的聯合更新條目。

編輯

由於雷蒙德的Hettinger指出(謝謝!),它是更好地使用

 uniques[col].update(chunk[col].unique()) 
+0

哇 - 這是在1/3的代碼伎倆。我還需要工作在字典上。做得好。 – RDS

+0

@RDS謝謝。我喜歡你的問題。祝一切順利。 –

+0

這會看起來更好用''set.update''而不是''set.union''。 –