【Python・Tableau基礎 | PythonでData saber】Order1 fundamental 後編(2/2)
さて、この記事がData saber課題1の最終回になります。
振り返ってみてみると、エクセルでよく使っているピボットテーブルのデータ集計やデータテーブルはもちろん二重軸による可視化の表現まで基礎的な範囲での可視化が多くあった気がします。
Q12.オーダー日の全ての曜日で、利益率が15%を切っている年はありますか。#datetime,折れ線グラフ
ちょうど直前の問題が、4年間の中で顧客数が最も多い特定曜日を選ぶ問題でありましたが、今回は年度も新しいカテゴリの項目として入ることになっていますね。
前作で整形させたデータフレームを利用してやってみます。
#オーダー日の曜日を表示するセールを作成
df_store['オーダー日_曜日'] = df_store['オーダー日'].dt.day_name()
#オーダー日の年度を表示するセールを作成
df_store['オーダー日_年'] = df_store['オーダー日'].dt.year
#年度や曜日を元に売上や利益を集計する
grouped_df = df_store.groupby(['オーダー日_年', 'オーダー日_曜日'])[['売上','利益']].sum().reset_index()
#利益を%で表示する
grouped_df['利益率'] = grouped_df['利益'] / grouped_df['売上']
# 曜日の順序を指定
days_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
# オーダー日_曜日列をカテゴリ型に変換し、順序を指定
grouped_df['オーダー日_曜日'] = pd.Categorical(grouped_df['オーダー日_曜日'], categories=days_order, ordered=True)
# 年度を昇順に固定し、オーダー日曜日を指定した曜日の順序を基に並び替え
grouped_df = grouped_df.sort_values(by=['オーダー日_年', 'オーダー日_曜日'])
# 結果を表示
print(grouped_df)
▼結果物
前回同様曜日を指定した順序で変更を加えています。
また、利益率は売上対しての利益の割合であるので、そちらも合わせて表示しています。
さてそれを用いて、折れ線グラフを作成してみました。
#カテゴリが年度である曜日別利益率の折れ線グラフを作成
plt.figure(figsize=(10, 6))
for year in grouped_df['オーダー日_年'].unique():
year_data = grouped_df[grouped_df['オーダー日_年'] == year]
plt.plot(year_data['オーダー日_曜日'], year_data['利益率'], label=year)
#カテゴリの凡例を右上に表示
plt.legend(title='年', loc='upper right')
#y値が0.15に補助線を描く
plt.axhline(y=0.15, color='black', linestyle='--')
# グラフのタイトルと軸ラベルを設定
plt.title('利益率 by 曜日')
plt.xlabel('曜日')
▼結果物
axhlineメッソドを利用して、基準となる補助線を設定しています。
このグラフをみると、全ての曜日で利益率15%を下回っているのは、2016年であることが分かりますね!
Q14.2013年で一番売上が低い月と2015年で一番売上が高いつきだけの平均金額は、全月の平均金額よりも高いですか?#plt.subplot(),反復文を活用した複数グラフの表示
今回の問題は、ただデータフレームを集計及び編集させるだけだはなく、特定の値を抜き取る必要がありそうですね。。
必要な工程としては、該当する売上データを抽出し、平均を出すことから、全月の平均と照らし合わせることですかね?
まずは、事前準備のため、必要な前処理をgroupby.mean()を使いやってみましょう。
#オーダー日の年度を表示するセールを作成
df_store['オーダー日_年'] = df_store['オーダー日'].dt.year
#オーダー日の月を表示するセールを作成
df_store['オーダー日_月'] = df_store['オーダー日'].dt.month
#売上の平均金額を年度、月を軸に集計
grouped_df = df_store.groupby(['オーダー日_年', 'オーダー日_月'])['売上'].mean().reset_index()
#結果表示
print(grouped_df)
▼結果物
ここから、特定のデータの抽出が始まります。
そして、そのデータの平均と全ての月のデータの平均との大小比較までやってみます。比較は単純にif文によるものでやっています。
# 2013年に一番売上が低い月を特定
lowest_sales_2013 = grouped_df[grouped_df['オーダー日_年'] == 2013].nsmallest(1, '売上')
# 2015年に一番売上が高い月を特定
highest_sales_2015 = grouped_df[grouped_df['オーダー日_年'] == 2015].nlargest(1, '売上')
# 結果を表示
print("2013年に一番売上が低い月:")
print(lowest_sales_2013[['オーダー日_月',"売上"]])
print("\n2015年に一番売上が高い月:")
print(highest_sales_2015[['オーダー日_月',"売上"]])
#2013年度の一番低い売上と2015年の高い売上の平均値
mean_sale = (lowest_sales_2013['売上'].values[0]+highest_sales_2015['売上'].values[0])/2
#結果表示
print("二つの売上値の平均: {:,.0f}".format(mean_sales))
#全月の結果を表示
print("全月の売上値の平均: {:,.0f}".format(grouped_df['売上'].mean()))
#二つの値の大小比較
if mean_sales > grouped_df['売上'].mean():
print("二つの平均値は、全月の平均値よりも高いです。")
else:
print("二つの平均値は、全月の平均値よりも低いです。")
▼結果物
おお高いという結果が出ましたね!(笑)
答えは分かったものの、きれいに可視化もしてみたいと思います。
今回のものは若干難易度が高く、各年度べつの月次データを合わせて表示する必要があります。想定イメージは4年分の月次データを横長にくっつげる折れ線グラフですかね?計4年分なので、4つの折れ線グラフを横長に並べることですかね?
これfor i in xxといった反復文で作成可能です!
# 年度ごとのユニークな値を取得
years = grouped_df['オーダー日_年'].unique()
# サブプロットを作成
fig, axes = plt.subplots(1, len(years), figsize=(20, 5), sharey=True)
# 各年度ごとの折れ線グラフを作成
for i, year in enumerate(years):
year_data = grouped_df[grouped_df['オーダー日_年'] == year]
axes[i].plot(year_data['オーダー日_月'], year_data['売上'], marker='o')
axes[i].set_title(f'{year}年')
axes[i].set_xlabel('月')
axes[i].set_xticks(range(1, 13)) # 月の範囲を1から12に設定
# 共通のy軸ラベルを設定
fig.text(0.04, 0.5, '売上', va='center', rotation='vertical')
# グラフのタイトルを設定
plt.suptitle('各年度の月次売上', fontsize=16)
# グラフを表示
plt.tight_layout(rect=[0.03, 0.03, 1, 0.95])
plt.show()
▼結果物
使用したメッソドは下記の内容がその説明となります。
・plt.subplot():複数のサブプロットを作成します。ここでは1行に年度の数分の列を持つサブプロットを作成しています。
・enumerate():リストの要素をインデックスとともに取得します。
・axes[i].plot:サブプロットに折れ線グラフを描画します。
・axes[i].set_xticks:x軸の目盛りを設定します。ここではrange関数から設定した、1から12までの整数値を設定しています。
・plt.suptitle:図全体のタイトルを設定します。:
・plt.tight_layout:図のレイアウトを自動的に調整して、サブプロット間の重なりを防ぎます。
Tableau上では以下のようなグラフを作成されています。
Y軸目盛り線が一つにまとまっていて結構きれいにみえますね。。
自分の能力不足でまったくおなじものは作成できないですが、Tableauでは、このように、便利で目盛りの編集がきれいに修正できるので、使い便利かと思います。
Ord1は以上になります!次の時間は、新しい課題であるord3でお会いできればと思います!Adios!