LoginSignup
6
9

More than 5 years have passed since last update.

Python DataFrame ピボットグラフの上位5位(Top 5)のみ抽出して棒グラフに表示

Posted at

今回やりたいこと

前回の投稿でピボットグラフを作成しました。
テストデータは商品数が10種類と少ないのでなんとかグラフ表示しても問題ありませんでした。

これが、商品数が多いとグラフは見づらくなります。
ためしに前回の投稿で テストデータ作成した(makecsv.py)の 商品リストを増やしてみる

makecsv.py は 前回の投稿 Python Pandas DataFrameでピボットグラフを作成して棒グラフ表示 を参照ください
 https://qiita.com/kngsym2018/items/4b4a92f7069080e2ba83

makecsv.py
#商品リストの商品を増やしてみる
product = ['DRYER','IRON','PRINTER','SCANNER','FAX','RADIO','USB','FAN','LAMP','ROUTER',
           'TV','CAMERA','BOOK','DVD','iPhone','Android','CD','OVEN','PC','TOMICA'
           ]

その後、前回の投稿のpivot.py を実行
image.png

商品数が多いとちょっと見づらくなりますね。

今回はcsv日付期間内の商品数 上位5位(TOP 5) のみをグラフする方法を投稿します。

やりたいことのイメージ

image.png
image.png

テストデータ

 前回の投稿の makecsv.py で作成したCSVファイル(product.csv)を使用します。

ピボットグラフの上位5位(Top 5)のみ 抽出して棒グラフに表示

pivot_top5.py
# データの扱いに必要なライブラリ
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.dates as mdates

#CSVを読込み
url = r"D:\study\phyton\product.csv"
plt.style.use('seaborn-dark')

#DataFrameに入れる
df = pd.read_csv(url,parse_dates=[1])

#DataFrameに入れたデータをピボットして、商品別に集計
pv=df.pivot_table( values ='PCS',index = ['PRODUCT'], columns = ['DAYS'],aggfunc = 'sum', fill_value = 0 ,margins=True,margins_name='TOTAL')

#商品別集計数の降順でソート
pv.sort_values(by='TOTAL',ascending=False,inplace=True)

#上位5位のものを使用して、行列入れ替え
pvtop5=pv[:6].T

#TOTAL行、列の削除
drop_idx = ['TOTAL']
pvtop5.drop(drop_idx, inplace=True)

drop_col = ['TOTAL']
pvtop5.drop(drop_col, axis=1, inplace=True)


fig = plt.figure(figsize=(5, 4))
ax = fig.add_subplot(1,1,1)

#積み上げグラフを作成
pvtop5.plot(ax =ax ,kind='bar' , stacked=True)

#以下表示設定
plt.title("Daily goods sales (Top5)", fontsize=12)
plt.xlabel("", fontsize=7)
plt.ylabel("", fontsize=7)
plt.subplots_adjust(bottom = 0.2)
plt.tick_params(labelsize=7)
plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0, fontsize=7)
plt.subplots_adjust(left = 0.1, right = 0.8)

plt.show()

グラフ表示

image.png

6月1日~6月6日の商品別集計での上位5位は
TOMICA:135
PC:123
OVEN:111
CD:99
Android:87

となるので、グラフには売上げTOP5対象のグラフができた!

コード説明

1. ピボットテーブルを使用して、商品毎に集計(SUM)します

#DataFrameに入れたデータをピボットして、商品別に集計
pv=df.pivot_table( values ='PCS',index = ['PRODUCT'], columns = ['DAYS'],aggfunc = 'sum', fill_value = 0 ,margins=True,margins_name='TOTAL')

集計対象は[PCS]、集計キーは[PRODUCT]、列は[DAYS]で、PCSの集計方法は[SUM(合計)]、margins = True で小計され、margins_name='TOTAL' で小計列が[TOTAL]で表示されます。

上記処理で作成された pv(DataFrame)のイメージ
(Jupyterで確認)

image.png

2. 商品別集計順にソート(降順)します

sort_valuesを使用してDataFrame列のソート(降順)を実行。ソートした結果は同じDataFrameを
使用します(inplace=True) 

#商品別集計数の降順でソート
pv.sort_values(by='TOTAL',ascending=False,inplace=True)

ソートされた pv(DataFrame)のイメージ
(Jupyterで確認)

image.png

[TOTAL]列の降順で、DataFrameはソートしたもので置き換えてます

3.ソートされた結果を行列入れ替えを行います

処理イメージ
image.png

これを実現するのは、
DataFrameの行と列を入れ替える、属性T (もしくはメソッドtranspose())を使います。

#上位5位のものを使用して、行列入れ替え
pvtop5=pv[:6].T

あわせて、ここでTOP5のデータのみを対象にします。
[:6]にしているのは、[TOTAL]列がTOP1 にくるためです。
※[TOTAL]行はあとで削除します

行列入れ替えした pvtop5(DataFrame)のイメージ
(Jupyterで確認)

image.png

4.このまま、棒グラフにすると[TOTAL]列と行が表示されてしまうので[TOTAL]の行、列を削除します

#TOTAL行、列の削除
drop_idx = ['TOTAL']
pvtop5.drop(drop_idx, inplace=True)

drop_col = ['TOTAL']
pvtop5.drop(drop_col, axis=1, inplace=True)

[TOTAL]行、列を削除した pvtop5(DataFrame)のイメージ

image.png

これを棒グラフで表示
image.png

ピボットグラフの上位5位(Top 5)のみ抽出して棒グラフに表示ができた!

6
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
9