質問は①~④です。
ゴチャゴチャしていて読みづらく申し訳ございませんが、
意見、回答、いただけると幸いです。
python3
1# 実行待ちのタスクが直近1カ月でどれくらい予約されてるかの辞書です。 2# 時と分が逆になってます。 3# 曜日や日を表す数字が最後についたりつかなかったりします。 4# period 1=日次, 2=週次, 3=月次 5# time mm:hh:(曜日dow|日day) 6# 曜日(1:日曜-7:土曜)|日(1-31)]。 7lis = [ 8{'period': 2 'time': '00:01:7'} # 毎週土曜の01:00に実行 9{'period': 1 'time': '10:07'} # 毎日07:10に実行 10{'period': 2 'time': '00:01:2'} # 毎週月曜の01:00に実行 11{'period': 1 'time': '00:03'} # 毎日の03:00に実行 12{'period': 1 'time': '00:02'} 13{'period': 1 'time': '00:01'} 14{'period': 2 'time': '00:01:1'} 15{'period': 3 'time': '00:01:1'} 16{'period': 1 'time': '00:02'} 17{'period': 2 'time': '00:03:1'} 18{'period': 3 'time': '00:01:1'} 19{'period': 1 'time': '00:04'} 20{'period': 1 'time': '30:02'} 21{'period': 1 'time': '00:02'} 22{'period': 3 'time': '00:03:20'} # 毎月20日の03:00に実行 23]
python3
1lis2 = [] 2# mm:hhをhh:mmに変更したlis2を再作成 3for row in lis: 4 sp = row['time'].split(':') # 00:01 -> ['00', '01'] 5 time = "{}:{}".format(sp[1].zfill(2), sp[0].zfill(2)) 6 row['time'] = time 7 lis2.append(row) 8 9# periodごとにカウントするための辞書を用意 10daily = {} 11weekly = {} 12monthly = {} 13 14# periodごとのtimeごとに件数を数える 15for row in lis2: 16 if row['period'] == 1: 17 daily.setdefault(row['time'], 0) 18 daily[row['time']] += 1 19pprint(daily) 20""" 21 '01:02': 1, 22 '01:05': 2, 23 '01:10': 1, 24 '01:14': 1, ... 25""" 26df = pd.DataFrame(list(daily.items())) 27df.plot(kind='area', stacked=True, alpha=0.4) 28plt.show() 29plt.savefig("image.png")
上記のような使いにくい時系列データがあります。
このデータを加工し、periodごとのtimeごとに件数をカウントし、
pandasで横軸:time, 縦軸:件数のグラフを書きたいのですが、
スマートな方法はありますか。
現在はlis[x]['time']をmm:hhからhh:mmに変更し、
件数を数えるための辞書を3種類用意し、
ループして数えてます。
①hh:mmに変更せずとも、datetimeのstrtimeやら
pandasのなんやらで、上手いことできるんじゃなかろうか。
②mm:hh→hh:mmにする処理(splitで実装)、
もっと読みやすくて短い書き方はないのか。
③件数数える部分の処理(ループでインクリメントして実装)、
countメソッド?collections.Counter関数?その他?で上手くできるんじゃないか。
④件数を数えるなら、辞書かリストのどちらがいいか。
pandasで使うなら、リストの方がなんとなく使いやすそう。
⑤直近1カ月のグラフにするとして、weeklyとmonthlyの時系列データは同生成するか。
仮にtimeを'2018 12-07 02:30'のようなフォーマットにするとして、
weekly直近の4週間(4件分の辞書)やmonthly(1件分の辞書)は、
時間の加算をどうやって実装し、生成するのか(datetime,pandasで上手くできないか?)
-============================================
↓↓↓追記(2018_1203_0123)↓↓↓
-============================================
追記①
⑤の週次、月次グラフのイメージ画像を追加しました。
(画像では11-21から出てしまってますが)
現在から直近30日のperiodごとのtimeごとの推移を見たいです。
追記②
{'period': 2 'time': '00:01:2'} # WEEKLY 毎週月曜の01:00に実行
また、WEEKLYの分がまた厄介で可能なら落としたくないと考えています。
つまり、最後の:2を落として、
現在から4回先までのtimeデータを
4回 lis.append(データ)する?必要があります。
(12-03 01:00, 12-10 01:00, 12-17 01:00, 12-24 01:00)
追記③
groupbyの使い方がいまいちぴんと来てなくて、
groupbyの関連でvalue_countsを知ったので、一旦実装してみました。
MySQLでいうところの、
SELECT period, time, COUNT(*) FROM lis GROUP BY period, time ;
的な結果を得たいと考えています。
python3
1df = pd.DataFrame({'time': [row['time'] for row in lis]}) 2# >>> df[:] 3# time 4# 0 2018-12-31 21:00:00 5# 1 2018-12-07 20:30:00 6# 2 2018-12-02 12:10:00 7#pprint(df, width=273) 8 9df_count = df['time'].value_counts() 10# 2018-12-02 16:00:00 74 11# 2018-12-03 06:10:00 40 12# 2018-12-03 04:10:00 39 13#pprint(df_count) 14 15df = pd.DataFrame({'time': list(df_count.index.values), 'num': list(df_count.values)}) 16# time num 17#0 2018-12-03 01:00:00 74 18#1 2018-12-03 15:10:00 40 19#2 2018-12-03 04:00:00 39 20#pprint(df)