Smile Engineering Blog

ジェイエスピーからTipsや技術特集、プロジェクト物語を発信します

Dask備忘録

はじめに

今回は、Daskを触ってみたので使い方を備忘録もかねてまとめてみます。

Daskとは

Pythonでデータ分析や機械学習をする際によく利用するライブラリがPandasですが、
Pandasで大容量データを処理すると、

  • データがメモリに収まらない
  • 基本的に単一スレッドで処理が行われるため処理速度が遅い

といった問題があります。
この問題を解決するのに並列・分散処理を行えるライブラリのDaskはよく利用されています。

Daskは主にNumPy、Pandas、PyToolzのAPIをもつデータ構造を提供しています。

API ベースパッケージ
Dask Array NumPy ndarray
Dask DataFrame pandas DataFrame
Dask Bag PyToolz

インストール

PythonをAnacondaでインストールしていれば、デフォルトでインストールされています。
インストールされていない場合はpip install dask等でインストールしてください。

Dask.DataFrameで並列処理を試してみる

pandas.DataFrameは2次元の表形式のデータですが、
Dask.DataFrameでは、pandas.DataFrameを分割して処理を実行します。

f:id:jspnet:20200114005052p:plain

それでは以前に以下で使用したデータセットを用いて、Dask DataFrameを試してみます。

Pythonで機械学習(kaggle入門その2) - Smile Engineering Blog

import pandas as pd
import numpy as np
import dask.dataframe as dd

CSVファイルを読み込み、pandas.DataFrameに格納。

train = pd.read_csv('../input/train.csv') # 訓練用データの読み込み

pandasからDaskに変換。
引数にてデータをいくつのパーティションに分割するのかを指定している(2分割に指定)。

ddf = dd.from_pandas(train,2) # pandasからDaskに変換
ddf
Dask DataFrame Structure:
Id MSSubClass MSZoning LotFrontage LotArea Street Alley LotShape LandContour Utilities LotConfig LandSlope Neighborhood Condition1 Condition2 BldgType HouseStyle OverallQual OverallCond YearBuilt YearRemodAdd RoofStyle RoofMatl Exterior1st Exterior2nd MasVnrType MasVnrArea ExterQual ExterCond Foundation BsmtQual BsmtCond BsmtExposure BsmtFinType1 BsmtFinSF1 BsmtFinType2 BsmtFinSF2 BsmtUnfSF TotalBsmtSF Heating HeatingQC CentralAir Electrical 1stFlrSF 2ndFlrSF LowQualFinSF GrLivArea BsmtFullBath BsmtHalfBath FullBath HalfBath BedroomAbvGr KitchenAbvGr KitchenQual TotRmsAbvGrd Functional Fireplaces FireplaceQu GarageType GarageYrBlt GarageFinish GarageCars GarageArea GarageQual GarageCond PavedDrive WoodDeckSF OpenPorchSF EnclosedPorch 3SsnPorch ScreenPorch PoolArea PoolQC Fence MiscFeature MiscVal MoSold YrSold SaleType SaleCondition SalePrice
npartitions=2
0 int64 int64 object float64 int64 object object object object object object object object object object object object int64 int64 int64 int64 object object object object object float64 object object object object object object object int64 object int64 int64 int64 object object object object int64 int64 int64 int64 int64 int64 int64 int64 int64 int64 object int64 object int64 object object float64 object int64 int64 object object object int64 int64 int64 int64 int64 int64 object object object int64 int64 int64 object object int64
730 ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1459 ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
Dask Name: from_pandas, 2 tasks

上記を確認すると730行目にて2分割されていることがわかる。

次に、実際に計算処理を行います。
pandas、Daskにてmean関数の計算結果と処理時間の比較しました。

pandasの場合

%time train.mean()
Wall time: 283 ms

Id                  730.500000
MSSubClass           56.897260
LotFrontage          70.049958
LotArea           10516.828082
OverallQual           6.099315
OverallCond           5.575342
YearBuilt          1971.267808
YearRemodAdd       1984.865753
MasVnrArea          103.685262
BsmtFinSF1          443.639726
BsmtFinSF2           46.549315
BsmtUnfSF           567.240411
TotalBsmtSF        1057.429452
1stFlrSF           1162.626712
2ndFlrSF            346.992466
LowQualFinSF          5.844521
GrLivArea          1515.463699
BsmtFullBath          0.425342
BsmtHalfBath          0.057534
FullBath              1.565068
HalfBath              0.382877
BedroomAbvGr          2.866438
KitchenAbvGr          1.046575
TotRmsAbvGrd          6.517808
Fireplaces            0.613014
GarageYrBlt        1978.506164
GarageCars            1.767123
GarageArea          472.980137
WoodDeckSF           94.244521
OpenPorchSF          46.660274
EnclosedPorch        21.954110
3SsnPorch             3.409589
ScreenPorch          15.060959
PoolArea              2.758904
MiscVal              43.489041
MoSold                6.321918
YrSold             2007.815753
SalePrice        180921.195890
dtype: float64

Daskの場合

%time ddf.mean().compute()
Wall time: 178 ms

Id                  730.500000
MSSubClass           56.897260
LotFrontage          70.049958
LotArea           10516.828082
OverallQual           6.099315
OverallCond           5.575342
YearBuilt          1971.267808
YearRemodAdd       1984.865753
MasVnrArea          103.685262
BsmtFinSF1          443.639726
BsmtFinSF2           46.549315
BsmtUnfSF           567.240411
TotalBsmtSF        1057.429452
1stFlrSF           1162.626712
2ndFlrSF            346.992466
LowQualFinSF          5.844521
GrLivArea          1515.463699
BsmtFullBath          0.425342
BsmtHalfBath          0.057534
FullBath              1.565068
HalfBath              0.382877
BedroomAbvGr          2.866438
KitchenAbvGr          1.046575
TotRmsAbvGrd          6.517808
Fireplaces            0.613014
GarageYrBlt        1978.506164
GarageCars            1.767123
GarageArea          472.980137
WoodDeckSF           94.244521
OpenPorchSF          46.660274
EnclosedPorch        21.954110
3SsnPorch             3.409589
ScreenPorch          15.060959
PoolArea              2.758904
MiscVal              43.489041
MoSold                6.321918
YrSold             2007.815753
SalePrice        180921.195890
dtype: float64

pandasとDaskで同じ計算結果になり、
若干ではあるが、Daskのほうが早く処理が行われているという結果となった。

さいごに

今回は、単純な例でしたがDaskで簡単に並列処理を行うことができました。
処理速度はそんなに大きいデータでなかったので大きな差がでなかったので、
今後、大容量データでも試してみたいと思います。

参考文献

Python Dask で 並列 DataFrame 処理 - StatsFragments