Large, persistent DataFrame in pandas
我正在探索作为一个长期的SAS用户切换到python和pandas。
然而,在今天运行一些测试时,我惊讶地发现当尝试
使用SAS,我可以将一个csv文件导入到一个SAS数据集中,它可以和我的硬盘一样大。
在
我经常处理大文件,无法访问分布式计算网络。
原则上,它不应该耗尽内存,但是由于一些复杂的python内部问题(这是模糊的,但很长一段时间以来人们都知道它:http://github.com/pydata/pandas/issues/407),目前
目前还没有一个完美的解决方案(这里有一个冗长的解决方案:您可以将文件逐行转录到一个预先分配的numpy数组或内存映射文件——
韦斯当然是对的!我只是想提供一个更完整的示例代码。我对一个129 MB的文件也有同样的问题,解决方法是:
1 2 3 4 | 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` |
这是一个较旧的线程,但我只是想将我的解决方案转储到这里。我最初尝试过
现在,我只需使用for循环方法读取csv文件的块,然后逐步将它们添加到sqlite数据库中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 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() |
下面是我的工作流程。
1 2 3 4 5 6 7 8 9 | import sqlalchemy as sa import pandas as pd import psycopg2 count = 0 con = sa.create_engine('postgresql://postgres:pwd@localhost: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') |
根据文件大小,最好优化chunksize。
1 2 3 4 | for chunk in chunks: chunk.to_sql(name='Table', if_exists='append', con=con) count += 1 print(count) |
在数据库中有了所有数据之后,您可以从数据库中查询出所需的数据。
如果您想加载巨大的csv文件,dask可能是一个不错的选择。它模仿熊猫API,所以感觉与熊猫非常相似
链接到Github上的DASK
您可以使用Pytable而不是Pandas DF。它是为大型数据集设计的,文件格式为HDF5。所以处理时间比较快。