我有一個非常大的csv,我需要讀入。爲了使此速度更快並節省RAM使用量,我使用read_csv並將某些列的dtype設置爲np.uint32。問題是一些行缺少值,熊貓使用浮點數來表示這些值。在read_csv中跳過缺失值的行
- 是否可以簡單地跳過缺少值的行?我知道我可以在讀完整個文件後做到這一點,但這意味着在此之前我無法設置dtype,因此會使用太多的RAM。
- 在讀取數據期間是否可以將缺失值轉換爲我選擇的其他值?
我有一個非常大的csv,我需要讀入。爲了使此速度更快並節省RAM使用量,我使用read_csv並將某些列的dtype設置爲np.uint32。問題是一些行缺少值,熊貓使用浮點數來表示這些值。在read_csv中跳過缺失值的行
如果您在閱讀過程中填寫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
行被重複,這是一個公平的討價還價。此方法也可能比使用轉換器功能更快。
如果您顯示一些數據,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
中有大熊貓沒有的功能,做到這一點。您可以在常規的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也使用它)。
這似乎在RAM中創建了兩個輸入副本?第一個拷貝'記錄'在類型轉換之前具有整個文件。這正是我想要避免的。 – eleanora
可能'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
你會考慮預處理你的數據,比如'grep -v ,, infile.csv goodfile.csv嗎?你可能能夠以這種方式更快地消除「壞」的線路。但它取決於空值在* all *列中還是僅在某些列中是無效的。 –
@JohnZwinck你可以在基於Windows的機器上使用'grep'嗎? – Merlin
@美林:是的,我可以。 –