“%H:%M”の形の文字列を扱う

 

はじめに

Pythonの備忘録です.

%H:%M型の文字列,例えば”12:30″がkeyになっている辞書型(元はjson)のデータをいじる機会があり,うまく走査したくて工夫した話です.

いろいろ試行錯誤するうちにPythonらしい記法が多々でてきたのでまとめておきます.

対象のデータ

In [1]:
import json
f = open("sample.json", "r")
sample_dic = json.load(f)
sample_dic
Out[1]:
{'00:00': {'A': {'err': 0, 'flow': 1.0},
  'B': {'err': 0, 'flow': 2.0},
  'C': {'err': 0, 'flow': 3.0},
  'D': {'err': 0, 'flow': 4.0}},
 '00:01': {'A': {'err': 0, 'flow': 5.0},
  'B': {'err': 0, 'flow': 6.0},
  'C': {'err': 0, 'flow': 7.0},
  'D': {'err': 0, 'flow': 8.0}},
 '00:02': {'A': {'err': 0, 'flow': 1.0},
  'B': {'err': 0, 'flow': 2.0},
  'C': {'err': 0, 'flow': 3.0},
  'D': {'err': 0, 'flow': 4.0}}}

一部だけですが,イメージとしては4個の感知器が,毎分通行量をflowとして保存している感じ.

賢くないやりかた

datetimeモジュールを使うやり方です.

In [2]:
import datetime

#文字列型の時刻を設定
date_str = "00:00"

#datetime型に変換
d = datetime.datetime.strptime(date_str, "%H:%M")

for i in range(3):
    #キーとする前に文字列型に変換
    time_str = d.strftime("%H:%M")
    
    print(sample_dic[time_str]["A"]["flow"])
    
    #時刻を更新
    d = d + datetime.timedelta(minutes=1)
1.0
5.0
1.0

timedateは時刻を扱う際に役に立つモジュール.datetime.datetime.strptime(文字列, "%H:%M")で文字列をtimedate型に変換できる.

今回のプログラムでは,d.strftime("%H:%M")で文字列に戻している.

datetime.timedelta(minutes=1)で(微小)時間を扱うことが可能(今回は1分).

このやり方は,単純な作業をわざわざ複雑にしている典型例のように感じる.賢くない.

まあまあのやりかた

最初に,"00"から"23"までを要素とするhourのリストと"00"から"59"までを要素とするminuteのリストを作っておいて,その組み合わせでkeyを作成する方法.

In [3]:
import numpy as np

#str型の時・分のリストを作っておく

hour_list = list(map(lambda x: str("{0:02d}".format(x)), np.arange(0,24,1)))

minute_list = list(map(lambda x: str("{0:02d}".format(x)), np.arange(0,60,1)))

#各要素は文字列なので,":"を挟んで結合すれば,keyとして使える(省略)

hour_list
Out[3]:
['00',
 '01',
 '02',
 '03',
 '04',
 '05',
 '06',
 '07',
 '08',
 '09',
 '10',
 '11',
 '12',
 '13',
 '14',
 '15',
 '16',
 '17',
 '18',
 '19',
 '20',
 '21',
 '22',
 '23']

"{0:02d}".format(x)で0埋めしている.

lambda関数,mapについては,また別の機会にまとめたい.

一番単純なやりかた

辞書型なので,最小に.keys()ですべてのkeyを取得してしまえばよい.

In [4]:
key_list = sample_dic.keys()

for key in key_list:
    print(sample_dic[key]["A"]["flow"])
1.0
5.0
1.0

必ずすべての時間のデータにアクセスするならば,このコードが一番簡潔.

ただし,感知器によって集計する時間帯を変える,などの作業があるときは,「まあまあのやりかた」の方が汎用性は高いかも知れない.

おわりに

いろいろなアプローチがあるのは楽しいですね.どんどん工夫していきたいものです.

5