koji/メガネ男の日誌

日々の学び、活動状況を記録します。仕事のことは少なめ。

pythonのpandasで表を並び替えるテクニック

f:id:kj_man666:20200410200243j:plain

次のような各年度の各月の数字が並んでいる表があった場合、グラフ化しようとすると一筋縄ではいきませんよね。

f:id:kj_man666:20200410200426p:plain

参考)写真の表は下記をコピペすれば作成できます。

import pandas as pd
df = pd.DataFrame(
                    {
                        "year":[2015, 2016, 2017,2018,2019,2020],
                        1:[100, 200, 300, 400,500,600],
                        2:[500,600,700,800,900,1000],
                        3:[300,900,1200,1500,1800,2100],
                        4:[400,800,1200,1600,2000,2400],
                        5:[50,100,150,200,250,300],
                        6:[150,300,450,600,750,900],
                        7:[80,160,240,320,400,480],
                        8:[1,4,9,16,25,36],
                        9:[33,66,99,132,198,231],
                        10:[20,40,80,160,320,640],
                        11:[5,10,15,20,25,30],
                        12:[25,50,75,100,125,150]
                    }
                )

Excelならピポットテーブルを組んで、フィールドリストのΣ値を入れ替えることで下記の写真のような表が作成できるのですが、pythonではどのようにすればいいのか、つまづいたのでまとめてみました。

f:id:kj_man666:20200410202223p:plain

結論から言いますと、for 文と iloc を駆使することで、上記のような表に作り替えることができます。

さっそくコードを見てみましょう。

なお、今回のコードは以下のサイトを参考にさせていただきました。

datumstudio.jp

# ライブラリのインポート
import pandas as pd
import os
import matplotlib.pyplot as plt

# for文とiloc を駆使して組み替えた表を結合・集約するためのからっぽのDataFrameを作成。
df2 = pd.DataFrame()

# for文とiloc を駆使して、1か月ごとに表を組み替え

# 1月~12月の12回繰り返しのfor文
for i in range(1,13):

# インデックス(行)はilocの左半分の [0: , ... で全て抽出し、カラム(列)は右半分の [0 , i] で year カラムと、1番目~12番目にある各月のカラムを抽出
    df3 = df.iloc[0 : ,[0 , i ]]

# 新しく月の数字を入れる month カラムを作成
    df3["month"] = i

# 結合するにあたり、カラム名が 数字(例:1月は 1)のままだと結合がうまくいかないので、共通のカラム名(mount)に変更
    df3 = df3.rename(columns={i:"mount"})

# カラの表と、集計した1ヶ月分の表を結合。これを12か月分繰り返す。
    df2 = pd.concat([df2, df3]) 

カラムの並びや index の番号がぐちゃぐちゃなのが気になりますが、グラフ化しやすい表が出来上がります。

f:id:kj_man666:20200410202424p:plain

グラフ化のために日付データのカラムを追加してあげましょう。

# 要素を文字列に変換した year カラムと 同じく文字列に変換した month カラム、適当に日は1にした times カラムを追加します。
df2["times"] = df2["year"].astype(str) + "/" + df2["month"].astype(str) +"/1"

# 文字データのままソートするとぐちゃぐちゃになるので、日付データに変換します。
df2["times"] = pd.to_datetime(df2["times"], format="%Y/%m/%d")

# times 列でソートします
df2 = df2.sort_values("times")

f:id:kj_man666:20200410203842p:plain

これできれいにグラフが作成できます!

plt.plot(df2["times"], df2["mount"])

f:id:kj_man666:20200410203924p:plain

さて、これで終わりでもよいのですが、せっかくなのでカラムを並び替えたり、インデックスをきれいにするテクニックもご紹介しましょう。

# loc[: ,[カラム名] で任意の列の並びで抽出しなおすことができます。  
df2 = df2.loc[:,["times","year", "month", "mount"]]

# index の順番を reset_index()で振りなおすことができます。  
# ただし、reset_index() を使うと、index という余計なカラムが新たに作成されてしまいますので、これをdrop()で削除します。  
df2 = df2.reset_index().drop("index", axis=1)

df2.head(100)

これでカラムも並び替えることができました!

f:id:kj_man666:20200410204745p:plain

以上になります、最後までお読みいただきありがとうございました。

参考サイト

note.nkmk.me

note.nkmk.me

note.nkmk.me

note.nkmk.me

it-ojisan.tokyo