Pandas中的大型持久数据框

a2mppw5e  于 2023-03-16  发布在  其他
关注(0)|答案(6)|浏览(157)

作为一个SAS的长期用户,我正在考虑改用python和panda。
然而,在今天运行一些测试时,我惊讶地发现python在尝试pandas.read_csv()一个128mb的csv文件时内存不足,这个文件大约有200,000行和200列,大部分是数字数据。
有了SAS,我可以将csv文件导入SAS数据集,它可以和我的硬盘一样大。
pandas中有类似的东西吗?
我经常处理大文件,无法访问分布式计算网络。

2exbekwf

2exbekwf1#

Wes当然是对的!我只是想提供一个更完整的示例代码。我在一个129 Mb的文件中遇到了同样的问题,这个问题可以通过以下方法解决:

import pandas as pd
    
# Returns a TextFileReader, which is iterable with chunks of 1000 rows.
csv_iterator = pd.read_csv('large_dataset.csv', iterator=True, chunksize=1000)
# Iterate through the dataframe chunks and print one row/record at a time
for chunk in csv_iterator:
    for index, row in chunk.iterrows():
        print(row)

# df is DataFrame. If errors, use `list(csv_iterator)` instead
df = pd.concat(tp, ignore_index=True)
e4yzc0pl

e4yzc0pl2#

原则上,它不应该耗尽内存,但是目前read_csv在处理大文件时存在内存问题,这是由一些复杂的Python内部问题引起的(这很模糊,但是很久以前就知道了:http://github.com/pydata/pandas/issues/407)。
目前还没有一个完美的解决方案(这里有一个乏味的解决方案:您可以将文件逐行转录到预先分配的NumPy数组或内存Map文件中--np.mmap),但这是我在不久的将来要做的工作。另一种解决方案是以较小的片段读取文件(使用iterator=True, chunksize=1000),然后与pd.concat连接。当您将整个文本文件一次性拉入内存时,问题就出现了。

hi3rlvi2

hi3rlvi23#

这是一个较老的线程,但我只是想在这里转储我的解决方案。我最初尝试了chunksize参数(即使值很小,如10000),但没有多大帮助;内存大小仍然有技术问题(我的CSV是~ 7. 5 GB)。
现在,我只是用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()
sigwle7e

sigwle7e4#

下面是我的工作流程。

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')

根据你的文件大小,你最好优化块大小。

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

在数据库中有了所有的数据后,你可以从数据库中查询出你需要的数据.

aiazj4mn

aiazj4mn5#

如果你想加载大的csv文件,dask可能是个不错的选择,它模仿了panda的API,所以感觉上和panda很像
link to dask on github

ejk8hzay

ejk8hzay6#

你可以使用Pytable而不是panda df,它是为大数据集设计的,文件格式是hdf5,所以处理时间相对较快。

相关问题