2017-03-20 24 views
4

私は使用する必要のある情報が含まれている10GBのCSVファイルを持っています。Pythonで巨大なCSVファイルを逐次読み込みます

私のPC上のメモリが限られているため、メモリ内のすべてのファイルを1つのバッチで読み取ることができません。代わりに、私はこのファイルのいくつかの行だけを繰り返し読みたいと思います。

最初の繰り返しでは最初の100を読んでいて、2番目のものは101から200になるなどとします。

このタスクをPythonで効率的に実行する方法はありますか? パンダはこれに便利なものを提供していますか?あるいは、(メモリとスピードの面で)より良い方法がありますか?

+0

多分:https://stackoverflow.com/questions/10717504/is-it-possible-to-use-read-csv-to-read-only-specific-lines – languitar

+0

それはですがpythonでさまざまなやり方で可能ですが、時にはファイルを(例えば 'split -l 100 filename'を使って)小さなファイルに分割するより現実的です。 – sphere

答えて

2

ここでは短い答えです。

chunksize = 10 ** 6 
for chunk in pd.read_csv(filename, chunksize=chunksize): 
    process(chunk) 

これは非常に長い回答です。

まず、pandasとsqlalchemyをインポートする必要があります。以下のコマンドはそれを行います。

import pandas as pd 
from sqlalchemy import create_engine 

次に、csvファイルを指す変数を設定します。これは必須ではありませんが、再利便性に役立ちます。

file = '/path/to/csv/file' 

この3つのコードでは、データの分析を開始する準備が整いました。コンテンツがどのように見えるかを見るためにcsvファイルの '頭部'を見てみましょう。

print pd.read_csv(file, nrows=5) 

このコマンドは、5行(NROWS = 5)に読み出されて、画面にそれらの行を印刷するためにパンダ 『read_csv』コマンドを使用します。これにより、csvファイルの構造を理解し、データがあなたの作業に合ったフォーマットになっていることを確認できます。

実際にデータを処理する前に、データのサブセットを処理するためにフィルタリングを開始できるように、データを処理する必要があります。これは通常、私がパンダのデータフレームを使用するものですが、大きなデータファイルでは、他の場所にデータを格納する必要があります。この場合、ローカルのsqlliteデータベースをセットアップし、csvファイルをチャンクで読み込み、そのチャンクをsqlliteに書き込みます。

これを行うには、まず次のコマンドを使用してsqlliteデータベースを作成する必要があります。

csv_database = create_engine('sqlite:///csv_database.db') 

次に、CSVファイルを塊で繰り返し、sqlliteにデータを格納する必要があります。このコードでは

chunksize = 100000 
i = 0 
j = 1 
for df in pd.read_csv(file, chunksize=chunksize, iterator=True): 
     df = df.rename(columns={c: c.replace(' ', '') for c in df.columns}) 
     df.index += j 
     i+=1 
     df.to_sql('table', csv_database, if_exists='append') 
     j = df.index[-1] + 1 

、私たちは、イテレータのカップル(I = 0、J = 0)を初期化し、その後のためのループを実行し、管理しやすいチャンクの大きさを保つために100,000チャンクサイズを設定しています。 forループは、CSVファイルからデータの塊を読み取り、列名のいずれかのスペースを削除してから、そのチャンクをsqlliteデータベース(df.to_sql(...))に格納します。

これは、CSVファイルが十分に大きい場合には時間がかかることがありますが、メモリの制約を気にすることなくデータベースからデータを引き出すためにpandasのSQLツールを使用できるので、我々が取得しようとしている問題がある、メモリにすべてのデータをロードします「* ...を選択」を使用して、もちろん

df = pd.read_sql_query('SELECT * FROM table', csv_database) 

では、次のようなコマンドを実行することができ、今のデータにアクセスするには離れてからあなたはあなたのselect文にフィルタを投げてデータをフィルタリングするべきです。たとえば、次のように

df = pd.read_sql_query('SELECT COl1, COL2 FROM table where COL1 = SOMEVALUE', csv_database) 
関連する問題