Japan
サイト内の現在位置
FrovedisのDataFrameを使ったデータ操作
no.0112021.5.31 今回はFrovedisのDataFrameを使用した操作についてご紹介します。
データ分析に際しては、様々なデータ蓄積場所、例えばCSVファイルのような小規模データファイル、構造型・非構造型データベース、Spark、Hadoopといった大規模なデータ保管場所などから必要なデータを取り込み、何らかの前処理を実施します。Pythonではデータの取り込み先として、標準ライブラリが持つList, Dictionary, Tupleなどのデータ形式を選択することができますし、データコンテナとしての柔軟な操作機能を有するNumpyやpandasを使用することも考えられます。
これらの中で、pandasはラベル付けされたデータ構造、データ整形のための機能をデータ分析者に提供します。pandasを使用して複数テーブルのマージ、データの集約、スライシングを実施した後に、データの統計的情報を確認することやデータ分析アルゴリズムを使った分析に進むことが可能です。ListやDictionary形式に収められたデータを扱うためには大なり小なり処理コードを作る必要に迫られますが、pandasを使うと多くのことをDataFrameが持つ機能を使って実現できます。また多くの場合に当てはまることですが、loop処理によってListやDictionary形式のデータに何らかの変更を加えるより、Numpyのユニバーサル関数やpandasのメソッドを使用するほうがより高速に実施できます。また、大規模なデータになるほどその差は広がります。
本コラム第9回でFrovedisがSparkの分散メモリ上のデータを使用したデータ分析をSX-Aurora TSUBASAにオフロードできることを書きました。そこまで大規模なデータを扱わない場合はpandasのDataFrameでデータを取り込み、FrovedisのDataFrameに変換します。これに伴いデータはx86からSX-Aurora TSUBASAのVector Engineのメモリへ転送されます。そのうえで前処理しFrovedisで分析処理することが可能です。
FrovedisのDataFrameが提供する機能はpandas版のサブセットに相当します。Select、Join、Sort、Groupbyといった操作機能を提供するほか、pandas DataFrameとの間でデータを受け渡しする関数を使用することができます。必要に応じてNumpyの多次元配列オブジェクトを用いた数学的演算処理やpandasの時系列データの取り扱い、データ入出力機能と連携することで、柔軟なデータ整形を実施します。
以下、Jupyter notebookを使用しながらFrovedis DataFrameの操作例を見ていきます。
初めに小規模な架空データを使い、select、sort、groupby等によるデータ操作を実行します。
サンプルデータを使用したFrovedis DataFrame操作例¶
import os
import numpy as np
import pandas as pd
from frovedis.exrpc.server import FrovedisServer
from frovedis.dataframe.df import FrovedisDataframe
Frovedis serverを起動します。¶
FrovedisServer.initialize("mpirun -np 2 {}".format(os.environ['FROVEDIS_SERVER']))
'[ID: 1] FrovedisServer (Hostname: handson02, Port: 42383) has been initialized with 2 MPI processes.'
2種類のサンプルデータを辞書形式で用意した後にpandas DataFrameを経由しFrovedis DataFrameへ変換します。pandasからFrrovedisのDataFrameに変換される際にデータがSX-Aurora TSUBASAのメモリに転送されます。¶
peopleDF = {
'Ename' : ['Michael', 'Andy', 'Tanaka', 'Raul', 'Yuta'],
'Age' : [29, 30, 27, 19, 31],
'Country' : ['USA', 'England', 'Japan', 'France', 'Japan']
}
countryDF = {
'Ccode' : [1, 2, 3, 4],
'Country' : ['USA', 'England', 'Japan', 'France']
}
pdf1 = pd.DataFrame(peopleDF)
pdf2 = pd.DataFrame(countryDF)
fdf1 = FrovedisDataframe(pdf1)
fdf2 = FrovedisDataframe(pdf2)
Frovedis DataFrameを表示します。¶
# display created frovedis dataframes
print ("* print Frovedis DataFrame")
print(fdf1.to_pandas_dataframe())
print(fdf2.to_pandas_dataframe())
* print Frovedis DataFrame Ename Age Country index 0 Michael 29 USA 1 Andy 30 England 2 Tanaka 27 Japan 3 Raul 19 France 4 Yuta 31 Japan Ccode Country index 0 1 USA 1 2 England 2 3 Japan 3 4 France
column名を指定し列を選択します。¶
# select demo
print ("* select Ename and Age")
print(fdf1[["Ename","Age"]].to_pandas_dataframe())
* select Ename and Age Ename Age 0 Michael 29 1 Andy 30 2 Tanaka 27 3 Raul 19 4 Yuta 31
"年齢"、"国名"を指定したフィルタリングを実施します。¶
# filter demo
print ("* filter by Age > 19 and Contry == 'Japan'")
print(fdf1[fdf1.Age > 19 and fdf1.Country == 'Japan'].to_pandas_dataframe())
* filter by Age > 19 and Contry == 'Japan' Ename Age Country 0 Tanaka 27 Japan 1 Yuta 31 Japan
"年齢"でソートします。¶
# sort demo
print ("* sort by Age (descending order)")
print(fdf1.sort("Age",ascending=False).to_pandas_dataframe()) # single column, descending
* sort by Age (descending order) Ename Age Country 0 Yuta 31 Japan 1 Andy 30 England 2 Michael 29 USA 3 Tanaka 27 Japan 4 Raul 19 France
複数のColumnを指定してソートします。¶
print ("* sort by Country and Age")
print(fdf1.sort(["Country", "Age"]).to_pandas_dataframe()) # multiple column
* sort by Country and Age Ename Age Country 0 Andy 30 England 1 Raul 19 France 2 Tanaka 27 Japan 3 Yuta 31 Japan 4 Michael 29 USA
"国名"によるグループ分けを実施後、各グループにおける年齢の最大値、最小値、平均値を集計します。¶
# groupby demo
print ("* groupby Country and max/min/mean of Age and count of Ename")
out = fdf1.groupby('Country')
out = out.agg({'Age': ['max','min','mean']})
out2 = out[["Country","max_Age","min_Age","mean_Age"]]
print(out2.to_pandas_dataframe())
* groupby Country and max/min/mean of Age and count of Ename Country max_Age min_Age mean_Age 0 England 30 30 30.0 1 Japan 31 27 29.0 2 France 19 19 19.0 3 USA 29 29 29.0
column名を変更します。¶
# renaming demo
print ("* rename Contry to Cname")
fdf3 = fdf2.rename({'Country' : 'Cname'})
print(fdf3.to_pandas_dataframe())
* rename Contry to Cname Ccode Cname index 0 1 USA 1 2 England 2 3 Japan 3 4 France
column名を指定し2つのDataFrameを統合します。¶
# join after column renaming
print ("* merge (join) two tables")
out = fdf1.merge(fdf3, left_on="Country", right_on="Cname") # with defaults
print(out.to_pandas_dataframe())
* merge (join) two tables Ename Age Country Ccode Cname index 0 Michael 29 USA 1 USA 1 Andy 30 England 2 England 2 Tanaka 27 Japan 3 Japan 3 Raul 19 France 4 France 4 Yuta 31 Japan 3 Japan
2つのDataFrameの統合、ソートを実施後、selectした結果を表示します。¶
# operation chaining: join -> sort -> select -> show
print ("* chaining: merge two tables, sort by Age, and select Age, Ename and Country")
out = fdf1.merge(fdf3, left_on="Country", right_on="Cname") \
.sort("Age")[["Age", "Ename", "Country"]]
print(out.to_pandas_dataframe())
* chaining: merge two tables, sort by Age, and select Age, Ename and Country Age Ename Country 0 19 Raul France 1 27 Tanaka Japan 2 29 Michael USA 3 30 Andy England 4 31 Yuta Japan
DataFrame内データの統計情報を表示します。¶
# column statistics
print ("describe: ")
print (fdf1.describe())
print ("\n")
describe: Age count 5.000000 mean 27.200000 std 4.816638 sum 136.000000 min 19.000000 max 31.000000
PandasのDataFrameとFrovedis DataFrameを統合して新たなFrovedis DataFrame "joined"を作成します。¶
# merging with panda dataframe
print ("* merge with pandas table")
pdf2.rename(columns={'Country' : 'Cname'},inplace=True)
joined = fdf1.merge(pdf2, left_on="Country", right_on="Cname")
print(joined.to_pandas_dataframe())
* merge with pandas table Ename Age Country Ccode Cname index 0 Michael 29 USA 1 USA 1 Andy 30 England 2 England 2 Tanaka 27 Japan 3 Japan 3 Raul 19 France 4 France 4 Yuta 31 Japan 3 Japan
Frovedis DataFrameをPandas DataFrameに変換します。¶
# conversion
print ("* convert Frovedis DataFrame to Pandas DataFrame")
print (fdf1.to_pandas_dataframe())
print ("\n")
* convert Frovedis DataFrame to Pandas DataFrame Ename Age Country index 0 Michael 29 USA 1 Andy 30 England 2 Tanaka 27 Japan 3 Raul 19 France 4 Yuta 31 Japan
FrovedisServer.shut_down()
続いて、KaggleのCovid-19 vaccineデータを使った操作例を見ていきます。