質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
COUNT

COUNT は、広く使用されているSQLの関数です。COUNT関数は、行数、もしくは配列のエンティティの数をカウントします。

DateTime

多くのプログラミング言語におけるDateTimeオブジェクトは、日付と時間に関する演算と出力を行います。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

1回答

507閲覧

使いにくい時系列データをスマートに処理したい

musuka

総合スコア10

COUNT

COUNT は、広く使用されているSQLの関数です。COUNT関数は、行数、もしくは配列のエンティティの数をカウントします。

DateTime

多くのプログラミング言語におけるDateTimeオブジェクトは、日付と時間に関する演算と出力を行います。

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2018/12/01 19:13

編集2022/01/12 10:55

質問は①~④です。
ゴチャゴチャしていて読みづらく申し訳ございませんが、
意見、回答、いただけると幸いです。

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)

↓月次のイメージ↓
月次のイメージ

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2018/12/01 20:32

⑤の週次、月次グラフのイメージが不明です。手書きでもよいので図示ください。
guest

回答1

0

⑤週次、月次グラフイメージが不明ですが、おそらくこのようなものだろうとアタリをつけて作成してみました。
①②についてはスマートな方法はないと思います。
③④についてはpandasのgroupbyにまかせると楽できます。

Python

1import pandas as pd 2import matplotlib.pyplot as plt 3 4lis = [ 5 {'period': 2 , 'time': '00:01:7'}, # 毎週土曜の01:00に実行 6 {'period': 1 , 'time': '10:07'}, # 毎日07:10に実行 7 {'period': 2 , 'time': '00:01:2'}, # 毎週月曜の01:00に実行 8 {'period': 1 , 'time': '00:03'}, # 毎日の03:00に実行 9 {'period': 1 , 'time': '00:02'}, 10 {'period': 1 , 'time': '00:01'}, 11 {'period': 2 , 'time': '00:01:1'}, 12 {'period': 3 , 'time': '00:01:1'}, 13 {'period': 1 , 'time': '00:02'}, 14 {'period': 2 , 'time': '00:03:1'}, 15 {'period': 3 , 'time': '00:01:1'}, 16 {'period': 1 , 'time': '00:04'}, 17 {'period': 1 , 'time': '30:02'}, 18 {'period': 1 , 'time': '00:02'}, 19 {'period': 3 , 'time': '00:03:20'} # 毎月20日の03:00に実行 20] 21 22# time列を日時に変換 23def toDT(row): 24 src = row['time'].split(':') 25 26 # 何日目かを特定 27 day = 1 28 if row['period'] == 2: 29 day = int(src[2]) # 曜日の情報は抜け落ちるが不要だろう 30 elif row['period'] == 3: 31 day = int(src[2]) 32 33 # 2018年1月基準の日時に変換 34 from datetime import datetime 35 dt = datetime(2018,1,day,int(src[1]),int(src[0])) 36 row['time'] = dt 37 38 return row 39 40df = pd.DataFrame( {'period':[v['period'] for v in lis], 'time':[v['time'] for v in lis]}) 41df = df.apply(toDT,axis=1) # time列を日時に変換 42print(df) 43 44for per in [1,2,3]: # 日、週、月次 45 grp = df[df['period'] == per].groupby('time') 46 df2 = grp.count().reset_index() 47 48 df2.plot(kind='area', stacked=True, alpha=0.4,x='time') # x軸はtimeとする 49 plt.savefig('{}.png'.format(per)) 50 plt.show()

イメージ説明
イメージ説明
イメージ説明

投稿2018/12/01 20:55

can110

総合スコア38234

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

musuka

2018/12/02 16:39

回答ありがとうございます。 > ①②についてはスマートな方法はないと思います。 残念ですが、splitで実装してみます。 > ③④についてはpandasのgroupbyにまかせると楽できます。 groupbyの使い方がイマイチ理解できていません。 pandas3日くらい勉強してみましたが、全然理解が進まず、 良さげな参考書でも買って読んでみようかと思います。 > ⑤の週次、月次グラフのイメージ イメージの画像を添付しました。 まだ、日、週、月次のデータをどう可視化するかまとまってないですが、 グラフを2個(あるいは3個?)用意して、 グラフ1はDAILY(period: [1])を X軸: 00:00-23:59の時系列を1時間単位で Y軸: (period=[1]の)timeごとの件数 グラフ2はMONTHKY(period: [1, 2, 3]を X軸: 現在から直近1カ月の時系列を1時間単位で Y軸: (period=[1, 2, 3]の)timeごとの件数を 表示しようと考えてます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問