本記事では学習のアウトプットとして、『Python実践データ分析100本ノック』に書かれている各ノックのコードのうち、難解と思われる部分の意味を解説していきます。「本に書かれている解説だけでは理解が難しい(;一_一)」と感じた方、この記事を読んで理解の一助となれば幸いです。
Python実戦データ分析100本ノックは、データの集計や分析のためのpandasや、グラフ描画に使用するmatplotlib、機械学習を行うためのscikit-learnなど、データ分析に欠かせない要素を実際に自分で手を動かしながら学ぶことができる本です。
今回は第2回として、ノック6-10をやっていきます。
追記:現在第二版が2022年6月に出版されています。
本記事は第1版の内容の解説です。
第二版の解説記事もいずれ書かせていただこうと思っていますので今しばしお待ちください!
第1章 ウェブからの注文数を分析する10本ノック
この章では、データファイルが一元管理されておらず、さまざまなファイルに分散しているデータを読み込むことから始まり、分散していたデータ同士を結合、必要な列を抽出する、といった加工処理を施していきます。最終的には、加工したデータから月別・商品別といったグループの分け方でそれぞれのデータの集計を行い、グラフを描きます。
ノック6:データ検算をしよう
#join_dataのprice 列の合計とtransactionのprice列の合計が同じことを確認しています。
#.sum()は、組み込み関数とよばれる、いつでも利用できる関数の1つで、総和を返します。
join_data["price"].sum() == transaction["price"].sum()
データの検算として、集計により算出したpriceとインポートしてきたpriceのトータルを比較して等しいかどうかを調べています。
ノック7:各種統計量を把握しよう
#isnull()は、指定した要素ごとに欠損値かどうかを判定し、True/Falseで結果を返します。
#欠損値があればTrue、欠損値がなければFalseと示してくれます。
#今回は、組み込み関数のsum()を用いているので、欠損値を示すTrueの総和を表示しています。
join_data.isnull().sum()
#describeメソッドは各列ごとに平均値、標準偏差、最大値、最小値、最頻値といった統計量を一覧表示できます。
join_data.describe()
join_dataの中のquantity,priceといった列ごとに平均値、最小値、最大値を自動的に算出してくれています。
ノック8:月別でデータを集計してみよう
#dtypesで、対象のデータ(今回は、join_data)のデータ型を確認しています。
join_data.dtypes
加工したいデータ(payment_date)の型を確認し、object型であることを確認できます。月別でデータ集計を行いたいので、次のコードでdatetime型という型に変更しておきます。
#to_datetimeで、payment_dateを日時を表す文字列datetime(日付と時刻)に変換できます。
#payment_dateは年-月-日-時刻という形式になっています。
join_data["payment_date"] = pd.to_datetime(join_data["payment_date"])
#strftime関数は引数に指定した書式文字列の形式でdatetimeを表示できます。%Y:西暦年を表示。%m:月を表示。
#そして、payment_monthという新たな列に形式を変えた後のpayment_dateを格納しています。
join_data["payment_month"] = join_data["payment_date"].dt.strftime("%Y%m")
join_data[["payment_date", "payment_month"]].head()
#groupbyは、対象のデータ(今回はjoin_data)を引数で指定した(今回はpayment_month)データごとに集計方法を指定(今回はsumつまり総和)して表示できます。
#sum()の横の[]でjoin_dataのprice列のみを表示させています。
join_data.groupby("payment_month").sum()["price"]
時系列でデータを集計したいので、まず最初にデータの型をdatetimeに変換し、年月までの情報表示にした後、月ごとにprice列をグルーぷ化し集計しています。
ノック9:月別、商品別でデータを集計してみよう
#ノック8と同様にpayment_monthとitem_nameごと(月別と商品別)にprice(売上)とquantity(数量)の総和を集計します。
join_data.groupby(["payment_month","item_name"]).sum()[["price", "quantity"]]
#pandasのpivot_tableメソッドを用いてデータ集計を行います。
#index=:行の指定ができ、結果の行見出しになります。
#columns=列の指定ができ、結果の列見出しになります、
#values=:集計する列を指定ができます。
#aggfunc=:集計方法の指定ができます(指定しない場合は自動的に平均値となります)。
pd.pivot_table(join_data, index='item_name', columns='payment_month', values=['price', 'quantity'], aggfunc='sum')
月別、商品別でデータを集計した後、ピボットテーブルを使用して、より視認性の高いテーブルを作成しました。
ノック10:商品別の売上推移を可視化してみよう
#ノック9と同様にpayment_monthを行に指定(月別)し、列にitem_name(商品名)を列に、priceの総和を集計します。
graph_data = pd.pivot_table(join_data, index='payment_month', columns='item_name', values='price', aggfunc='sum')
graph_data.head()
#matplotlibを読み込みます。
import matplotlib.pyplot as plt
%matplotlib inline
#plt.plotで折れ線グラフを指定、繰り返し記述することで1つのグラフ内に複数の折れ線をプロットします。
#plot(x,y)の形式でx軸とy軸にデータを指定できます。
#今回は、上のコードで作成したgraph_dataリストのindex(payment_month)をx軸に指定します。
#商品ごとの売上を表示したいので、graph_dataの商品名の列を指定することでそれぞれの商品のpriceをy軸にしています。
#label=''でラベル名を設定できます。
plt.plot(list(graph_data.index), graph_data["PC-A"], label='PC-A')
plt.plot(list(graph_data.index), graph_data["PC-B"], label='PC-B')
plt.plot(list(graph_data.index), graph_data["PC-C"], label='PC-C')
plt.plot(list(graph_data.index), graph_data["PC-D"], label='PC-D')
plt.plot(list(graph_data.index), graph_data["PC-E"], label='PC-E')
#plt.legend()で凡例を表示させます。
plt.legend()
ここまでで、ノック6~10は完了です。お疲れ様でした。下準備を施したデータを用いてテーブルを作成し、グラフを描くことができました。次回は2章に入ります。引き続きよろしくお願いいたします(^^)/。