プログラミング
記事内に商品プロモーションを含む場合があります

Pandasで大規模データを扱う時にメモリ消費を抑える手法を紹介

Aru

Pandasでデータが大きすぎて読み込めない場合、効率的にデータを扱うためのいくつかの方法があります。本記事では、巨大データを効果的に読み込むためのテクニックを解説します。具体的には、必要な列だけを選択して読み込む方法、データをチャンクごとに分割して処理する方法、さらにはデータの型を明示的に指定してメモリを節約する手法について解説します。

はじめに

Pandasで大規模データを扱う場合、メモリ不足でデータが読み込めないことがあります。

ここでは、大規模データを処理する場合に、メモリ使用量を抑えるためのテクニックをいくつか紹介します。また、実際にテクニックを使った場合にどの程度メモリ消費を抑えることができたかについて実際のコードを提示しながら解説したいと思います。

データ処理に慣れている人にはお馴染みの手法ですが、kaggleなどのコンペでも有用な方法ですので覚えておくと良いと思います。

メモリ使用量を抑える方法

列を指定して読み込む

列数(カラム数)は大量だけど、データ分析等に必要な列はその一部な場合、必要な列だけを読み出すことでメモリ使用量を抑えることが可能です。

以下は、具体的なコードの例です。下記のコードでは、large_data.csvcolumn1~3だけを指定して読み込んでいます。

import pandas as pd

df = pd.read_csv('large_data.csv', usecols=['column1', 'column2', 'column3'])

データを分割して読み込む

行ごとに処理を行う場合や、全行のデータなくても処理できる場合、データを塊(チャンク)ごとに読み込んで処理を行うことでメモリ消費量を抑えることが可能です。

以下は、具体的なコードの例です。下記のコードでは、chunk_size=1000として、10,000行単位で読み込みます。なお、for文では、例えば「各行に対して処理(統計量計算など)したデータを保存する」「条件に一致するデータだけを抽出する」や、「加工してファイルへ保存する」などの処理を行います。

import pandas as pd

chunk_size = 10000 

for chunk in pd.read_csv('large_data.csv', chunksize=chunk_size):
    # 各チャンクに対して処理を行う
    # 例: 必要なデータをフィルタリング・統計計算、データクリーニング、ファイルへの保存など

データ型を指定してデータ量を減らす

Pandasでは、型を指定しないとデフォルトでは整数はint64、浮動小数点はfloat64で読み込まれます。pandasでは、整数はint8, int16, int32, int64, 浮動小数点はfloat32, float64を指定することができるので、データの範囲に応じて型を指定することでメモリ消費量を抑えることが可能です。

例えば、年齢はint8(0~255)の範囲で十分なので、int64からint8に変えればデータ量を1/8にできます。

以下は、具体的なコードの例です。下記のコードでは、column1, column2をそれぞれint32, float32で読み込んでいます。

df = pd.read_csv('large_data.csv', dtype={'column1': 'int32', 'column2': 'float32'})

実践

実際にダミーデータを作成して、上記のテクニックでどの程度メモリ消費量を抑えることができるか確認してみます。

ダミーデータを作成する

下記はダミーデータの作成コードです。ダミーデータは10万行×100列の0~10,000の範囲の乱数データです。各列はcolumn1~column100というラベルが付けられています。

このデータのメモリ使用量は76.29MBです

import pandas as pd
import random

cols = 100
rows = 100_000
datas = {"column"+str(idx+1): [random.randint(0, 10000) for _ in range(rows)] for idx in range(cols)}


df = pd.DataFrame(datas)
df.to_csv("table.csv", index=False)

memory_usage = df.memory_usage(deep=True).sum()
print(f'DataFrame memory usage: {memory_usage/1024/1024 : .2f} Mbytes')
# DataFrame memory usage:  76.29 Mbytes

そのまま読み込む

まず、保存したダミーデータをそのまま読み込んでみました。

読み込んだデータのメモリ使用量は76.29MBでした

df = pd.read_csv("table.csv")
memory_usage = df.memory_usage(deep=True).sum()
print(f'DataFrame memory usage: {memory_usage/1024/1024 : .2f} Mbytes')
# DataFrame memory usage:  76.29 Mbytes

カラム(列)を指定して読み込む

次に列を指定して読み込んでみました。読み込みは10列に1列です。

読み込んだデータのメモリ使用量は7.63MBでした。読み込むカラム数を1/10にしたので、メモリ使用量もちょうど1/10になっています。

sel = ['column'+str(idx+1) for idx in range(0, cols, 10)]
df = pd.read_csv("table.csv", usecols=sel)
memory_usage = df.memory_usage(deep=True).sum()
print(f'DataFrame memory usage: {memory_usage/1024/1024 : .2f} Mbytes')
# DataFrame memory usage:  7.63 Mbytes

データの型を指定して読み込む

データの型を指定して読み込んでみました。このデータは0~10000の範囲なので、16bit(int16)で収まる範囲です。

読み込んだデータのメモリ使用量は19.07MBでした。int64からint16にしたので、メモリ消費量も1/4になりました。

types = {'column'+str(idx+1): 'int16' for idx in range(cols)}
df = pd.read_csv("table.csv", dtype=types)
memory_usage = df.memory_usage(deep=True).sum()
print(f'DataFrame memory usage: {memory_usage/1024/1024 : .2f} Mbytes')
# DataFrame memory usage:  19.07 Mbytes

データ型指定とカラム(列)指定を併用

データ型と列指定は併用することも可能です。

読み込んだデータのメモリ使用量は1.91MBでした。int64からint16と1/4、列数も100から10の1/10したので、メモリ消費量も1/40になりました。

sel = ['column'+str(idx+1) for idx in range(0, cols, 10)]
types = {'column'+str(idx+1): 'int16' for idx in range(0, cols, 10)}
df = pd.read_csv("table.csv", usecols=sel, dtype=types)
memory_usage = df.memory_usage(deep=True).sum()
print(f'DataFrame memory usage: {memory_usage/1024/1024 : .2f} Mbytes')
# DataFrame memory usage:  1.91 Mbytes

分割読み込み(参考)

最後にチャンク読み込みの例です。具体的なチャンクに分割するコードは以下のようになります。

chunk_size = 10000
for i, chunk in enumerate(pd.read_csv('table.csv', chunksize=chunk_size)):
    print(i, len(chunk))
    print(chunk)

まとめ

以上、Pandasのデータ読み込みでメモリ消費量を抑える方法について解説しました。メモリ消費量を抑えるように加工したデータはparquetなどのフォーマットで保存しておけば、データの型などを指定することなく読み込むことが可能です。

あわせて読みたい
pandasでCSV, Pickle, Parquetの読み書き速度とファイルサイズを比較検証
pandasでCSV, Pickle, Parquetの読み書き速度とファイルサイズを比較検証

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ABOUT ME
ある/Aru
ある/Aru
IT&機械学習エンジニア/ファイナンシャルプランナー(CFP®)
専門分野は並列処理・画像処理・機械学習・ディープラーニング。プログラミング言語はC, C++, Go, Pythonを中心として色々利用。現在は、Kaggle, 競プロなどをしながら悠々自適に活動中
記事URLをコピーしました