PandasのDataFrameでDatetimeIndexを曜日順に並びかえるの巻

PandasのDataFrameでDatetimeIndexを曜日順に並びかえるの巻

PandasのDataFrameでDatetimeIndexから取得した曜日を曜日順に並べる方法のメモ

経緯

Datetimeindexからweekday_nameを取得してソートするとアルファベット順になるので月火水・・・でソートさせてください。。。

↓こういうDataFrame(weekdayとyearがDatetimeIndex,のMultiindex, kmがcolumn)があったときに。。。

                   km
weekday   year
Tuesday   2019   11.7
Wednesday 2019   12.4
Thursday  2019    8.7
Friday    2019   14.8
Saturday  2019    3.0
Sunday    2019    9.5
Monday    2019    1.3

↓このように曜日でソートしたいっていうだけなんですけど。。。

                  km
weekday   year
Monday    2019   1.3
Tuesday   2019  11.7
Wednesday 2019  12.4
Thursday  2019   8.7
Friday    2019  14.8
Saturday  2019   3.0
Sunday    2019   9.5

↓普通にsort_indexを使うと。。。あら、アルファベット順に並んじゃって全然ピンとこない。。。月火水木金土日で並べたいだけなんじゃあたしは。

                  km
weekday   year
Friday    2019  14.8
Monday    2019   1.3
Saturday  2019   3.0
Sunday    2019   9.5
Thursday  2019   8.7
Tuesday   2019  11.7
Wednesday 2019  12.4

っていう話。

やり方

csvデータの読み込みから並びかえて出力するまでの一通りの手順を記載します。

データ読み込み

y-m-d,km
2019/7/30,11.7
2019/7/31,12.4
2019/8/1,8.7
2019/8/2,14.8
2019/8/3,3
2019/8/4,9.5
2019/8/5,1.3

これはワタシのジョギングの記録を一週間分抜粋したものです。(日付, 走行距離のcsvファイル; distance.csv)。
これを曜日ごとに走った距離をまとめてみよう、という試みです。ちなみに7月30日は火曜日でした。

とりあえずpandasで読み込んでDataFrameにします

#!/usr/bin/env python
# coding: utf-8

#pandasをpdとして読み込む
import pandas as pd

#read_csvメソッドでCSVファイルを読み込んでpandasのdataframeとする。これをdfとした。
#csvファイル(distance.csv)は期間2019.7.20-2019.8.5でジョギングした距離を記録したもの

#pandasで読み込み。
#コンマで分ける。日付はparseしてDatetime型とし、最初の要素(y-m-d)をindexに指定してDatetimeIndexとする。
df = pd.read_csv("distance.csv", sep="," , parse_dates= True, index_col=0)

#データを表示して確認する
print(df)
              km
y-m-d    
2019-07-30  11.7
2019-07-31  12.4
2019-08-01   8.7 
2019-08-02  14.8
2019-08-03   3.0 
2019-08-04   9.5 
2019-08-05   1.3 

一応データ型を確認してみる

#  各列のデータ型を確認
print('dateframeの列のデータ型>>>\n', df.dtypes)

print()
#  indexの確認
print('indexは>>>\n', df.index)

print()
# columnの確認
print('columnは>>>\n', df.columns)

日付の列がちゃんとDatetimeIndexになってます。よしよし、これで曜日名が取り出せる。

dateframeの列のデータ型>>>
 km    float64
dtype: object

indexは>>>
 DatetimeIndex(['2019-07-30', '2019-07-31', '2019-08-01', '2019-08-02','2019-08-03'],
              dtype='datetime64[ns]', name='y-m-d', freq=None)

columnは>>>
 Index(['km'], dtype='object')

曜日名を取り出してMultiindex化する

#index.weekday_nameで曜日名、index.yearで年を取り出してindexとし、multiindex化しておく
df_weekdayname = df.set_index([df.index.weekday_name, df.index.year])

#確認
print(df_weekdayname)
                   km
y-m-d     y-m-d
Tuesday   2019   11.7
Wednesday 2019   12.4
Thursday  2019    8.7
Friday    2019   14.8
Saturday  2019    3.0
Sunday    2019    9.5
Monday    2019    1.3
#index名をわかりやすいものに変更。
df_weekdayname.index.names = ['weekday', 'year']

#確認
print(df_weekdayname)
                   km
weekday   year
Tuesday   2019   11.7
Wednesday 2019   12.4
Thursday  2019    8.7
Friday    2019   14.8
Saturday  2019    3.0
Sunday    2019    9.5
Monday    2019    1.3

このままだと見にくいので並べ替えたい、と。

でもsort_indexして並べ替えると、冒頭のようにアルファベット順に並んでしまう。。。

そういうわけで以下の方法で並べかえました。他にやり方あるかも知らんですが。

曜日を月火水・・・の順で並べ替える

月火水で並べた曜日のリストを作っておいて、reindexにて元あったindexと差しかえます。

levelでMultiindexのweekdayのほうを指定し、labelsに用意しておいたyoubiを入れます。

#曜日のリストを作っておく
youbi = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

#曜日をちゃんと並ぶように並びかえる。これをtatemukiとした。
tatemuki = df_weekdayname.reindex(level='weekday', labels=youbi)

#確認
print(tatemuki)

↓これでよしと。

                  km
weekday   year   
Monday    2019   1.3
Tuesday   2019  11.7
Wednesday 2019  12.4
Thursday  2019   8.7
Friday    2019  14.8
Saturday  2019   3.0
Sunday    2019   9.5

ついでにmatplotlibで視覚化してみる。

#matplotlibで視覚化してみる
import matplotlib as mpl
import matplotlib.pyplot as plt

#種類を棒グラフ、legend(凡例)なし。
ax = tatemuki.plot(kind ='bar', legend=False)

#X軸の目盛ラベルをtatemuki.index.levels[0](曜日)にする
ax.set_xticklabels(tatemuki.index.levels[0])

#X軸ラベルは無し、Y軸ラベルはKm, 種類はbar
ax.set_xlabel('')
ax.set_ylabel('Km')
ax.plot(kind = 'bar')

#サイズオーバーの際に見切れないように表示する
plt.tight_layout()

#表示する
plt.show()
pandas_matplotlib_gpaph

曜日ごとのデータを見やすい状態で確認できるようになりました。

ちなみに横向きの表を並べ替える場合

↓これ(df_weekdayname)を

weekday   year
Friday    2019  14.8
Monday    2019   1.3
Saturday  2019   3.0
Sunday    2019   9.5
Thursday  2019   8.7
Tuesday   2019  11.7
Wednesday 2019  12.4

横向きにして、

#reset_index().pivotにてyearをindexに、weekdayをcolumnに振り直す。kmはvaluesのまま。
df_weekdayname_reset = df_weekdayname.reset_index().pivot('year', 'weekday', 'km')
weekday  Friday  Monday  Saturday  Sunday  Thursday  Tuesday  Wednesday
year
2019       14.8     1.3       3.0     9.5       8.7     11.7       12.4

並べ替え。

#reindexを使用して、先ほど用意しておいたyoubiに差し替え。横向き(行方向)なのでaxis=1を指定。
yokomuki = df_weekdayname_reset.reindex(youbi, axis=1)
weekday  Monday  Tuesday  Wednesday  Thursday  Friday  Saturday  Sunday
year
2019        1.3     11.7       12.4       8.7    14.8       3.0     9.5

または次のやり方でも

pd.DataFrame(df_weekdayname_reset).loc[:, youbi]

もしくは

pd.DataFrame(df_weekdayname_reset).loc[:, ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']]

でいける。めでたしめでたし。



このブログはエックスサーバー で運営しております。




WordPressを使うならロリポップ!
簡単インストール完備で楽々スタート!

世界にたった一つ、あなただけのドメインを登録しよう!
格安ドメイン取得サービス─ムームードメイン─