私はpythonおよびpandas= as as long-time SAS user。
しかし、今日いくつかのテストを実行しているとき、128MBのCSVファイルをpandas.read_csv()
しようとするとpythonメモリ不足になりました。主に数値データ。
SASを使用すると、csvファイルをSASデータセットにインポートでき、ハードドライブと同じ大きさにすることができます。
pandas
に類似したものはありますか?
私は定期的に大きなファイルを扱っており、分散コンピューティングネットワークにアクセスできません。
原則として、メモリ不足になるべきではありませんが、現在、複雑なPython内部問題(これはあいまいですが、それは知られています)によって引き起こされる大きなファイルの_read_csv
_にメモリの問題があります長い間: http://github.com/pydata/pandas/issues/407 )。
現時点では完全な解決策はありません(面倒な解決策は次のとおりです:ファイルを行ごとに事前に割り当てられたNumPy配列またはメモリマップファイルに転写することができます---np.mmap
_)私は近い将来に取り組んでいきます。別の解決策は、ファイルを小さな断片で読み取り(_iterator=True, chunksize=1000
_を使用)、_pd.concat
_で連結します。問題は、1つの大きな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.5 Gbでした)。
現在、私はfor-loopアプローチで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()
以下は私の作業の流れです。
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)
すべてのデータをデータベースに保存したら、データベースから必要なデータを照会できます。
巨大なcsvファイルをロードする場合は、daskが適切なオプションです。 pandas apiを模倣しているため、パンダと非常によく似ています
pandas df。ではなくPytableを使用できます。大きなデータセット用に設計されており、ファイル形式はhdf5です。したがって、処理時間は比較的高速です。