【Python実践データ分析100本ノック】ノック16-20

python実践データ分析100本ノック解説 python データ分析
スポンサーリンク

本記事では学習のアウトプットとして、『Python実践データ分析100本ノック』に書かれている各ノックのコードのうち、難解と思われる部分の意味を解説していきます。「本に書かれている解説だけでは理解が難しい(;一_一)」と感じた方、この記事を読んで理解の一助となれば幸いです。

Python実戦データ分析100本ノックは、データの集計や分析のためのpandasや、グラフ描画に使用するmatplotlib、機械学習を行うためのscikit-learnなど、データ分析に欠かせない要素を実際に自分で手を動かしながら学ぶことができる本です。

今回は第4回として、ノック16-20をやっていきます。

 

追記現在第二版が2022年6月に出版されています

本記事は第1版の内容の解説です

第二版の解説記事もいずれ書かせていただこうと思っていますので今しばしお待ちください!

スポンサーリンク

第2章 小売店のデータでデータ加工を行うノック10本

この章では、大まかな流れは第1章と同じで、複数のデータを読み込み、結合した後で集計することです。しかし、第1章から異なるのは、読み込んだデータ内に表記の揺れがあることです。表計算ソフトを使用していても、例えば、名前を記入する時、人によって半角スペースを使う人もいれば、全角スペースを使う人もいるのではないでしょうか?指定されていても誤ってしまう場合もありますよね。そんな人的ミスを自動的に修正していきます。

ノック16:顧客名の揺れを補正しよう

#ノック14と同様にstr.replace()で、全角スペース→スペース無しへの変換をしています。
kokyaku_data["顧客名"] = kokyaku_data["顧客名"].str.replace(" ", "")
#こちらも同様に半角スペース→スペース無しへの変換をしています。
kokyaku_data["顧客名"] = kokyaku_data["顧客名"].str.replace(" ", "")
kokyaku_data["顧客名"].head()

顧客名の揺れを補正するために全角スペースと半角スペースを消しました。

ノック17:日付の揺れを補正しよう

#"登録日"の形式が数値と日付とでバラバラになっています。これを補正します。まずは数値形式のデータの数を調べます。
#astype(“str”)はキャストといって、対象のデータのデータ型を引数で指定した型(今回はstr型)に変換できます。
#これを行わないと、次の操作でstrのメソッドがつかえません。
#strのisdigit()メソッドは1文字以上の文字列の中のすべての文字が数字かどうかを調べることができます。
#すべて数字であればTrueです。
#str型にキャストした"登録日"データのうち数値となっているデータをflg_is_serialに格納しています。
flg_is_serial = kokyaku_data["登録日"].astype("str").str.isdigit()
flg_is_serial.sum()

#to_timedeltaは対象のデータ(今回は、loc関数でflg_is_serialの内"登録日")をタイムデルタに変換します。
#タイムデルタは差分単位(月、日、分、秒)で表現された時間のことです。
#datetime;日時(2000/4/1 12:00:00)、timedelta:経過時間(00:00:15)といったイメージです。
#基準となる時刻からどれだけ経過したかを計算できます。
#astypeメソッドは引数にパラメータを指定するとデータを指定した型に変換できます。
#今回はfloat(浮動小数点)を指定したので、0→0.0になります。
#unit=でD(日付)を指定したので、年月日まで(秒は入れず)をタイムデルタに変換します。
#pd.to_datetime(“1900/01/01”)で基準となる日を1900/01/01とし、基準日から登録日が何日たっているかを計算して正しい日付に修正しています。
fromSerial = pd.to_timedelta(kokyaku_data.loc[flg_is_serial, "登録日"].astype("float"), unit="D") + pd.to_datetime("1900/01/01")
fromSerial

数値データが含まれており、形式がバラバラだったデータを日付形式に補正しました。

ノック18:顧客名をキーに2つのデータを結合(ジョイン)しよう

#ノック3と同様にmergeメソッドでuriage_data,とkokyaku_dataを結合します。
#ただし、それぞれのテーブルには共通キーとなりそうな列があるものの、名前が異なります。
#そこで、left_on=で左側のテーブル(uriage_data)のキー”customer_name”、right_on=で右側のテーブル(kokyaku_data)のキー”顧客名”を指定して結合させます。
join_data = pd.merge(uriage_data, kokyaku_data, left_on="customer_name", right_on="顧客名", how="left")
#drop()は指定したデータ(今回は“customer_name)を削除します。
#ノック15にもあったようにaxis=1なので行を指定しています。
join_data = join_data.drop("customer_name", axis=1)
join_data

共通キーの名前が異なるテーブルでも結合できました。

ノック19:クレンジングしたデータをダンプ(ファイル出力)しよう

dump_data = join_data[["purchase_date", "purchase_month", "item_name", "item_price", "顧客名", "かな", "地域", "メールアドレス", "登録日"]]
dump_data
#to_csvで指定したデータを名前を指定しながらcsvファイルで出力できます。
#index=Falseとするのは、エクスポートされた CSV ファイルにはインデックスの列を含めさせないようにするためです。
#逆に含めてしまうと、再度インポートした際にカラムにUnnamedカラムが追加されてしまいます。
dump_data.to_csv("dump_data.csv", index=False)

いきなりデータを出力(ダンプ)するのではなく、データ列の並びを整えてから出力しました。

ノック20:データを集計しよう

#ノック9と同様にピボットテーブルを使用して、より視認性の高いテーブルを作成します。
#aggfunc="size"と"sum"の違いですが、
#例えば、データフレームに2列しかなく、indexとcolumnsにデータフレームの列をすべて指定してしまっていると、valuesで指定できる列がなくなります。
#その際、sumやcountを指定すると空白になってしまいますが、"size"を指定するとこれを回避できます。
byItem = import_data.pivot_table(index="purchase_month", columns="item_name", aggfunc="size", fill_value=0)
byItem
byPrice = import_data.pivot_table(index="purchase_month", columns="item_name", values="item_price", aggfunc="sum", fill_value=0)
byPrice
byCustomer = import_data.pivot_table(index="purchase_month", columns="顧客名", aggfunc="size", fill_value=0)
byCustomer
byRegion = import_data.pivot_table(index="purchase_month", columns="地域", aggfunc="size", fill_value=0)
byRegion

away_data = pd.merge(uriage_data, kokyaku_data, left_on="customer_name", right_on="顧客名", how="right")
#[“purchase_date”].isnull()でpurchase_dataを指定して欠損値がないかを調べます。
#NaNがある場合は“顧客名”, “メールアドレス”, “登録日”を表示させます。
away_data[away_data["purchase_date"].isnull()][["顧客名","メールアドレス","登録日"]]

ノック19でダンプしたデータを読み込み、必要な情報のみを指定してそれぞれのテーブルで集計結果を表示できました。

ここまでで、ノック15-20は完了です。お疲れ様でした。 形式がバラバラだったデータを補正(クレンジング)して集計したテーブルを作成できました。 次回は3章(機械学習)に入ります。引き続きよろしくお願いいたします(^^)/。