大Pandas中的大型持久数据帧

2024-05-23 23:33:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在探索切换到python和pandas作为一个长期的SAS用户。

然而,当今天运行一些测试时,我很惊讶python在试图pandas.read_csv()一个128mbcsv文件时内存不足。它有大约200000行和200列主要是数字数据。

有了SAS,我可以将csv文件导入SAS数据集,它可以和我的硬盘一样大。

pandas中有类似的东西吗?

我经常处理大型文件,无法访问分布式计算网络。


Tags: 文件csv数据用户网络pandasread数字
3条回答

原则上,它不应该耗尽内存,但目前由于一些复杂的Python内部问题(这是一个模糊的问题,但已经知道很长一段时间了:http://github.com/pydata/pandas/issues/407),大型文件上的read_csv存在内存问题。

目前还没有一个完美的解决方案(这里有一个乏味的解决方案:您可以逐行将文件转录成预先分配的NumPy数组或内存映射文件——np.mmap),但这是我将在不久的将来研究的解决方案。另一种解决方案是以较小的片段读取文件(使用iterator=True, chunksize=1000),然后与pd.concat连接。当你在一个大的slurp中把整个文本文件拉入内存时,问题就来了。

韦斯当然是对的!我只是想提供一个更完整的示例代码。我对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`

这是一个旧线程,但我只是想把我的解决方案扔在这里。我最初尝试了chunksize参数(即使使用非常小的值,比如10000),但没有太大帮助;在内存大小方面仍然存在技术问题(我的CSV是~7.5gb)。

现在,我只是以for循环的方式读取CSV文件的块,并将它们逐步添加到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()    

相关问题 更多 >