2016-08-07 74 views
2

我有一個非常大的csv,我需要讀入。爲了使此速度更快並節省RAM使用量,我使用read_csv並將某些列的dtype設置爲np.uint32。問題是一些行缺少值,熊貓使用浮點數來表示這些值。在read_csv中跳過缺失值的行

  1. 是否可以簡單地跳過缺少值的行?我知道我可以在讀完整個文件後做到這一點,但這意味着在此之前我無法設置dtype,因此會使用太多的RAM。
  2. 在讀取數據期間是否可以將缺失值轉換爲我選擇的其他值?
+1

你會考慮預處理你的數據,比如'grep -v ,, infile.csv goodfile.csv嗎?你可能能夠以這種方式更快地消除「壞」的線路。但它取決於空值在* all *列中還是僅在某些列中是無效的。 –

+0

@JohnZwinck你可以在基於Windows的機器上使用'grep'嗎? – Merlin

+0

@美林:是的,我可以。 –

回答

6

如果您在閱讀過程中填寫NaN並說0,這將是精美的。也許,在大熊貓的git的樞紐功能要求是爲了...

使用轉換器功能

但是,暫時,你可以定義自己的函數來做到這一點,並把它傳遞給converters說法在read_csv

def conv(val): 
    if val == np.nan: 
     return 0 # or whatever else you want to represent your NaN with 
    return val 

df = pd.read_csv(file, converters={colWithNaN : conv}, dtypes=...) 

注意converters需要dict,所以你需要指定它爲具有NaN的要處理每一列。如果很多色譜柱受到影響,它會變得有點令人厭煩。您可以指定列名或數字作爲關鍵字。

另請注意,這可能會降低您的read_csv性能,具體取決於converters函數的處理方式。此外,如果你只是有一列,需要讀取過程中的NaN處理,你可以跳過一個適當的功能定義和使用lambda函數:

df = pd.read_csv(file, converters={colWithNaN : lambda x: 0 if x == np.nan else x}, dtypes=...) 

讀入塊

你也可以閱讀該文件以小塊拼接在一起以獲得最終輸出。你可以這樣做一堆事情。以下是一個說明性示例:

result = pd.DataFrame() 
df = pd.read_csv(file, chunksize=1000) 
for chunk in df: 
    chunk.dropna(axis=0, inplace=True) # Dropping all rows with any NaN value 
    chunk[colToConvert] = chunk[colToConvert].astype(np.uint32) 
    result = result.append(chunk) 
del df, chunk 

請注意,此方法不嚴格重複數據。有一段時間chunk中的數據存在兩次,在result.append聲明之後,但只有chunksize行被重複,這是一個公平的討價還價。此方法也可能比使用轉換器功能更快。

+0

我想這取決於如果表中有任何NaN需要的輸入。 – Jasen

+0

@Jasen,這是代表僞代碼。這並不意味着替代品的下降。也許被讀取的數據是空的,所以'if'語句應該改爲'如果val是None:'。也許它有一些其他的代表... – Kartik

+1

謝謝。這回答了問題2.這個方法可以用來回答問題1嗎? – eleanora

-1

如果您顯示一些數據,SO ppl可以提供幫助。

pd.read_csv('FILE', keep_default_na=False) 

對於初學者嘗試這些:

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html

na_values : str or list-like or dict, default None 
Additional strings to recognize as NA/NaN. If dict passed, specific per-column NA values. By default the following values are interpreted as NaN: ‘’, ‘#N/A’, ‘#N/A N/A’, ‘#NA’, ‘-1.#IND’, ‘-1.#QNAN’, ‘-NaN’, ‘-nan’, ‘1.#IND’, ‘1.#QNAN’, ‘N/A’, ‘NA’, ‘NULL’, ‘NaN’, ‘nan’. 

keep_default_na : bool, default True 
If na_values are specified and keep_default_na is False the default NaN values are overridden, otherwise they’re appended to. 

na_filter : boolean, default True 
    Detect missing value markers (empty strings and the value of na_values). In data without any NAs, passing na_filter=False can improve the performance of reading a large file 
0

中有大熊貓沒有的功能,做到這一點。您可以在常規的Python實現這樣的:

import csv 
import pandas as pd 

def filter_records(records): 
    """Given an iterable of dicts, converts values to int. 
    Discards any record which has an empty field.""" 

    for record in records: 
     for k, v in record.iteritems(): 
      if v == '': 
       break 
      record[k] = int(v) 
     else: # this executes whenever break did not 
      yield record 

with open('t.csv') as infile: 
    records = csv.DictReader(infile) 
    df = pd.DataFrame.from_records(filter_records(records)) 

熊貓採用csv模塊內部反正。如果上述表現出現問題,您可以用Cython加速(Pandas也使用它)。

+0

這似乎在RAM中創建了兩個輸入副本?第一個拷貝'記錄'在類型轉換之前具有整個文件。這正是我想要避免的。 – eleanora

+0

可能'pandas.read_csv'也容易發生數據重複。至少它是,如果你讀熊貓的創造者Wes McKinny [這個博客] [1]。但請注意,該博客是在2012年10月撰寫的,就像博客上的免責聲明所說,已經有一段時間了,大部分信息都已過時。我不知道現代的,閃亮的'read_csv'在內存管理方面可以做什麼。 [1]:http://wesmckinney.com/blog/a-new-high-performance-memory-efficient-file-parser-engine-for-pandas/ – Kartik