10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

はじめに

「Pythonでデータ前処理」と言ったら、多くの方が「...Pandas!」となると思います。しかしPandasは大きなデータを扱うときに処理速度が遅いなんてことがあります。
そこで色々と調べていたら「Pandasで行うデータ処理を100倍高速にするOut-of-CoreフレームワークVaex」という、あまりにもキャッチーなタイトルのサイトがあったので、Vaexを少し触ってみました。
以下では簡単に、

  • Vaexとは何か?
  • Pandasと比較してどのぐらい早いの?
  • 結局PandasとVaexどっち使うの?

    を記載します。

Vaexとは何か?

必要なデータを適宜読み出して処理したり(アウトオブコア)、分散処理(マルチコア)を行って、データ処理を行えるのがVaexらしいです。
確かにPandasだとメモリに乗らないほどの大規模データの処理が大変だったりするので、早いだけでなく大規模データを扱うにも適しているんですね。

あとVaexではデータファイルをhdf5に書き換えて読みます。hdf5というのは、[フォルダ+データファイル]をひとまとめにしたファイルのことだそうです。(HDF5形式のファイル (1) HDF5って?より引用)
hdf5に書き換えて読むので、必要なデータを適宜読み出して処理する(アウトオブコア)ことができるんですね。

Pandasと比較してどのぐらい早いの?

結論から述べます。Vaexで実行できる処理なら処理速度は「(感覚的に)1億倍早い」です。処理を待っている時間は、通常よりも長く感じるので、本当に「(感覚的に)1億倍早い」です。
では実際に試した処理について、どの程度時間がかかったか記載していきます。
今回はASHRAE-Great Energy Predictor IIIのtrain.csvとbuilding_metadata.csvを利用していきます。
train.csvは20,216,100行4列で686.8 MB、 building_metadata.csvは1,449行6列で49KBです。

実行処理 Pandas Vaex
データの読み込み 10.2 0.0695
文字列をtimestampに変換 1.62 0.00368
データの結合 6.22 0.00102
timestampから年/月/日/曜日の情報抽出 5.55 0.0101
列同士の演算 3.93 0.00822
(仮)可視化 - ヒストグラム 0.919 0.575
GROUPBY(一部データで実行) 0.0032 0.00907
欠損値の確認 6.71 328!?
(※時間は全て秒)
(※Vaexでのデータの読み込みでは、hdf5ファイルを読み込んでいます。)

上記確認していただくとお分かりのように、大体の処理が事実2兆倍ぐらい早いことがわかります。
しかし欠損値の確認はヤバイです。何が起きたんだという感じです。Vaexで全列の欠損を確認する際は、forループを回さなければいけなそうだったので、これはこれでしょうがないのですかね。(何かいい方法あったら教えてください。)
ということで以下にコードを記載しておきます。

データの読み込み

%%time
pd_train = pd.read_csv('train.csv')
pd_buildingmeta = pd.read_csv('building_metadata.csv')
%%time
vx_train = vx.open('train.hdf5')
vx_buildingmeta = vx.open('building_metadata.hdf5')

文字列をtimestampに変換

%%time
pd_train['timestamp'] = pd.to_datetime(pd_train["timestamp"])
# vaexにはpd.to_datetime関数みたいな便利機能がないのでdatetimeモジュールを利用
%%time
vx_train['timestamp'] = vx_train["timestamp"].apply(lambda x: datetime.strptime(x, '%Y-%m-%d %H:%M:%S'))

データの結合

%%time
pd_train_buildingmeta = pd_train.merge(pd_buildingmeta, left_on='building_id',
             right_on='building_id')
%%time
vx_train_buildingmeta = vx_train.join(vx_buildingmeta, left_on='building_id',
              right_on='building_id', lprefix='train', rprefix='building')

timestampから年/月/日/曜日の情報抽出

%%time
pd_train_buildingmeta["year"] = pd_train_buildingmeta["timestamp"].dt.year
pd_train_buildingmeta["month"] = pd_train_buildingmeta["timestamp"].dt.month
pd_train_buildingmeta["day"] = pd_train_buildingmeta["timestamp"].dt.day
pd_train_buildingmeta["hour"] = pd_train_buildingmeta["timestamp"].dt.hour
pd_train_buildingmeta["minute"] = pd_train_buildingmeta["timestamp"].dt.minute
pd_train_buildingmeta["weekofyear"] = pd_train_buildingmeta["timestamp"].dt.weekofyear
%%time
vx_train_buildingmeta["year"] = vx_train_buildingmeta["timestamp"].dt.year
vx_train_buildingmeta["month"] = vx_train_buildingmeta["timestamp"].dt.month
vx_train_buildingmeta["day"] = vx_train_buildingmeta["timestamp"].dt.day
vx_train_buildingmeta["hour"] = vx_train_buildingmeta["timestamp"].dt.hour
vx_train_buildingmeta["minute"] = vx_train_buildingmeta["timestamp"].dt.minute
vx_train_buildingmeta["weekofyear"] = vx_train_buildingmeta["timestamp"].dt.weekofyear

列同士の演算

%%time
pd_train_buildingmeta['age_of_a_building'] = pd_train_buildingmeta['year'] - pd_train_buildingmeta['year_built']
%%time
vx_train_buildingmeta['age_of_a_building'] = vx_train_buildingmeta['year'] - vx_train_buildingmeta['year_built']

(仮)可視化 - ヒストグラム

%%time
pd_train_buildingmeta["meter_reading"].hist()

download.png

%%time
vx_train_buildingmeta.plot1d(vx_train_buildingmeta["meter_reading"], what="count(*)")

download.png
(...これは微妙)

GROUPBY(10,000行抽出して実行)

%%time
selected_pd_train.groupby("meter").agg({"meter_reading": "mean"})
%%time
selected_vs_train.groupby("meter").agg({"meter_reading": "mean"})

欠損値の確認

%%time
pd_buildingmeta.isnull().sum()
# forループを実装する以外の方法が見つからなかったため、forループを利用
%%time
for col in vx_buildingmeta.column_names:
    print(vx_buildingmeta[col].isna().sum())

結局PandasとVaexどっち使うの?

まあ列同士の演算とか文字列操作等の限られた操作&大規模データならVaexはいいかも。

しかし

  • multiple keyでのデータ結合ができない
  • 可視化が微妙
  • 欠損値の確認遅い  
    など一部歯痒いところがあったので、これからの改善に期待します。

参考サイト:
https://vaex.readthedocs.io/en/latest/
https://blog.ikedaosushi.com/entry/2019/04/14/173307
https://blog.ikedaosushi.com/entry/2019/04/14/003916
http://villageofsound.hatenadiary.jp/entry/2014/10/29/021605
http://www.nakl.t.u-tokyo.ac.jp/~masuda/papers/pnt07Symp.pdf

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?