icalendarデータから時間の使い方を集計するPythonプログラム

  • 1
    いいね
  • 0
    コメント

パッケージインストール

まずは、pip install icalendar
です。

次に分析に使う項目をExcelで作ります。

会議 資料作成 メール
朝ミーティング 会議資料準備 朝のメールチェック
昼ミーティング 報告資料作成 昼のメールチェック
夜ミーティング 夜のメールチェック

のように、1行目に分析したい単位の項目、2行目以降に、それぞれの分析単位の小項目を記載します。この小項目が、icalendarデータの検索キーワードになります。

項目表.xlsxとでも名付けて保存することにします。

次に分析対象のicalendarデータを用意します。

用意の方法はいろいろあると思います。
Outlookからのエクスポートとか簡単ですね。

次にソースです。

正直なところ、全然エレガントじゃないと思うんですが、初心者なので許してください、というか、どなたかご指導ください。

・項目表をまずは読み込んで、同じサイズのデータ集計用のdataframeを作成
・次々に、icalendarデータを読み込んで、項目表.xlsxから該当の座標を見つけて、対応する集計用のdataframeに、計算した時間を加算していっています。

メモリの無駄遣い?二重ループがエレガントじゃない、とかいろいろあると思うのでコメントください。

import numpy as np
import pandas as pd
import icalendar as ic
from datetime import timedelta


def calculate_time(event):
    start = event['DTSTART'].dt
    end = event['DTEND'].dt

    time = end -start

    return time.total_seconds() / 3600


def main():
    labels = pd.read_excel('./項目表.xlsx')
    print(labels)

    file = open('./testdata.ics', 'r', encoding='utf-8')
    cal = ic.Calendar.from_ical(file.read())

    data = pd.DataFrame(np.zeros((labels.shape[0], labels.shape[1])))
    data.columns = label.columns

    for event in cal.walk('vevent'):
        time = calculate_time(event)
        summary = str(event.get('summary'))

        for i in range(0, labels.shape[0]):
            for j in range(0, labels.shape[1]):
                if str(labels.iloc[i, j]) in summary:
                    data.iloc[i, j] = data.iloc[i, j] + time


    print(data)

if __name__ == '__main__':
    main()

なにやってるかわからないところあれば、御質問ください。
まだグラフ化していないですが、ここまでくれば、グラフ化は簡単なはず。

グラフ化の一例

円グラフにすることにします。

data.sum().plot.pie(legend=False, autopct="%.1f%%", textprops={'fontproperties': fp, 'fontsize':20})
plt.axis('equal')

legend=Falseで邪魔な凡例が出ないようにして、パーセンテージをautopct="%.1f%%"で表示するようにしています。

日本語フォントを使うときのポイントで調べるのに時間がかかったのが、textprops={'fontproperties': fp, 'fontsize':20}) の書き方です。pythonのplotで円グラフを使うときに日本語フォントを指定するにはどうしたらいいのか全然情報が見つからず、時間かかりました。

plt.axis('equal')は、円グラフがつぶれるのを防ぎます。

参考文献

https://gist.github.com/lukasmartinelli/9021795