2012-07-24 29 views
77

我正在探索作爲長期SAS用戶切換到python和pandas。熊貓中的大型持久數據框

但是,今天在運行一些測試時,我驚訝於python在嘗試pandas.read_csv() 128mb csv文件時內存不足。它有大約20萬行和200列的大部分數字數據。

使用SAS,我可以將csv文件導入到SAS數據集中,並且可以像我的硬盤一樣大。

pandas是否有類似的東西?

我經常使用大型文件,無法訪問分佈式計算網絡。

+0

我不熟悉的大熊貓,但你可能想通過通過文件迭代的樣子。 http://pandas.pydata.org/pandas-docs/stable/io。html#iterating-through-files-chunk-by-chunk – monkut 2012-07-24 01:02:08

回答

69

原則上它不應該耗盡內存,但目前由於一些複雜的Python內部問題(這是模糊的,但已知很長時間:http://github.com/pydata/pandas/issues/407)導致的大文件上存在read_csv內存問題。

目前還沒有一個完美的解決方案(這裏是一個單調乏味的解決方案:您可以逐行將文件轉錄成預分配的NumPy數組或內存映射文件 - np.mmap),但它是一個我會在不久的將來努力。另一種解決方案是以較小的文件讀取文件(使用iterator=True, chunksize=1000),然後與pd.concat連接。當你將整個文本文件拖入內存時,問題就出現了。

+1

說我可以讀取文件並將它們全部連接成一個DataFrame。 DataFrame是否必須駐留在內存中?藉助SAS,只要具有硬盤空間,我就可以處理任何大小的數據集。它與DataFrames相同嗎?我得到的印象是受RAM限制,而不是硬盤空間。對不起noob問題,並感謝您的幫助。我很喜歡你的書。 – Zelazny7 2012-07-24 01:46:02

+3

對,你受到內存的限制。 SAS確實對「非核心」大數據處理提供了更好的支持。 – 2012-07-24 04:12:59

+5

@WesMcKinney由於你登陸0.10的新csv加載器,不應再需要這些變通辦法了,對嗎? – 2013-07-29 11:44:40

71

韋斯當然是對的!我只是想提供一些更完整的示例代碼。我有同樣的問題與129 MB的文件,這是由解決:

from pandas import * 

tp = read_csv('large_dataset.csv', iterator=True, chunksize=1000) # gives TextFileReader, which is iterable with chunks of 1000 rows. 
df = concat(tp, ignore_index=True) # df is DataFrame. If errors, do `list(tp)` instead of `tp` 
+4

我認爲你可以做'df = concate(tp,ignore_index = True)'? – 2013-06-24 12:24:58

+0

@AndyHayden:當然!修正了。 – fickludd 2013-10-15 12:25:34

+0

@smci使用重複x4(550 Mb)或x8(1.1Gb)的相同數據快速嘗試此操作。有趣的是,有或沒有[x for x in tp],x4都很好,x8在MemoryError中崩潰。 – fickludd 2013-10-15 12:26:00

33

這是一個較舊的線程,但我只是想在這裏傾倒我的解決方法解決方案。我最初嘗試chunksize參數(即使像10000這樣的相當小的值),但它沒有多大幫助;內存大小仍然存在技術問題(我的CSV是〜7.5 Gb)。

現在,我剛纔讀的CSV文件的數據塊在for循環的方法,並逐步將它們添加例如,一個SQLite數據庫的步驟:

import pandas as pd 
import sqlite3 
from pandas.io import sql 
import subprocess 

# In and output file paths 
in_csv = '../data/my_large.csv' 
out_sqlite = '../data/my.sqlite' 

table_name = 'my_table' # name for the SQLite database table 
chunksize = 100000 # number of lines to process at each iteration 

# columns that should be read from the CSV file 
columns = ['molecule_id','charge','db','drugsnow','hba','hbd','loc','nrb','smiles'] 

# Get number of lines in the CSV file 
nlines = subprocess.check_output('wc -l %s' % in_csv, shell=True) 
nlines = int(nlines.split()[0]) 

# connect to database 
cnx = sqlite3.connect(out_sqlite) 

# Iteratively read CSV and dump lines into the SQLite table 
for i in range(0, nlines, chunksize): 

    df = pd.read_csv(in_csv, 
      header=None, # no header, define column header manually later 
      nrows=chunksize, # number of rows to read at each iteration 
      skiprows=i) # skip rows that were already read 

    # columns to read   
    df.columns = columns 

    sql.to_sql(df, 
       name=table_name, 
       con=cnx, 
       index=False, # don't use CSV file index 
       index_label='molecule_id', # use a unique column from DataFrame as index 
       if_exists='append') 
cnx.close()  
+2

超級有用看到對於分塊閱讀功能來說,這是一個現實的用例。謝謝。 – 2015-06-30 16:37:37

+4

這個老話題:只要提供'iterator = True'和'chunksize = chunksize','pandas.read_csv'就會直接返回(至少在我目前使用的版本上)一個迭代器。因此,您只需對'pd.read_csv'調用執行'for'循環,而不是每次都重新實例化它。但是,這隻需花費通話費用,可能沒有重大影響。 – 2015-12-08 15:19:29

+1

嗨,喬爾。謝謝你的提示!如果我沒有記錯,那麼'iterator = True'和'chunksize'參數已經存在。也許在舊版本中存在一個導致內存爆炸的bug - 下次我在Pandas中讀取一個大型DataFrame時,我會再試一次(我現在主要使用Blaze來完成這些任務) – Sebastian 2015-12-08 18:57:09

1

您可以使用Pytable而不是熊貓DF。 它設計用於大型數據集,文件格式爲hdf5。 所以處理時間相對較快。

1

以下是我的工作流程。

import sqlalchemy as sa 
import pandas as pd 
import psycopg2 

count = 0 
con = sa.create_engine('postgresql://postgres:[email protected]:00001/r') 
#con = sa.create_engine('sqlite:///XXXXX.db') SQLite 
chunks = pd.read_csv('..file', chunksize=10000, encoding="ISO-8859-1", 
        sep=',', error_bad_lines=False, index_col=False, dtype='unicode') 

根據您的文件大小,您最好優化塊大小。

for chunk in chunks: 
     chunk.to_sql(name='Table', if_exists='append', con=con) 
     count += 1 
     print(count) 

在數據庫中有所有數據後,您可以從數據庫中查詢出您需要的數據。

3

如果你想加載巨大的csv文件,dask可能是一個不錯的選擇。它模仿大熊貓的API,所以感覺非常相似,大熊貓

link to dask on github

+0

謝謝,自從我發佈以來這我一直在使用dask和鑲木地板格式。 – Zelazny7 2017-06-09 02:32:58