こんにちは
はじめに、以下のような補助的な関数を作っておきます。
python3
1def sec_to_time(s):
2 '''
3 引数 s で与えられる秒数を、0時0分0秒からの経過秒数として、
4 対応する time オブジェクトを作成して返す。
5 (引数 s は np.float64 の小数を想定)
6 '''
7 s = int(round(s))
8 h = s // 3600
9 s -= 3600 * h
10 m = s // 60
11 s -= 60 * m
12 return datetime.time(hour=h, minute=m, second=s)
13
14
15def time_to_sec(dt):
16 '''
17 引数 dt で与えられるdatetimeオブジェクトの示す日時の
18 時刻部分について、0時0分0秒からの経過秒数を返す
19 '''
20 return 3600 * dt.hour + 60 * dt.minute + dt.second
上記の time_to_sec
を使って、所与のデータフレームに、平均計算ののための一時的な列時刻(秒)
を追加します。
python3
1dfres.loc[:,'時刻(秒)'] = [*map(lambda t: time_to_sec(t), dfres['登録時刻'])]
上記によって、データフレームに、下記のような 時刻(秒)
列が追加されます。
登録時刻 時刻(秒)
0 2020-01-06 09:01:44 32504
1 2020-01-06 09:00:29 32429
・・・
時刻(秒)
列の平均を求めて、これを先に作った sec_to_time
に与えて、時刻を得ます。
python3
1sec_to_time(dfres['時刻(秒)'].mean())
追記
上記の回答コードは、補助的な関数の中で、3600
や 60
という数字を使って、時刻オブジェクトと数値の変換を行っており、煩雑でした。これらを使わない方法を考えたので追記します。
考え方としては、
① 所与のデータフレームの全行について、 登録時刻
列の日時の日付部分を 1970-01-01
に置き換えた日時を作り、それらに対して timestamp()
によってエポック秒を取得
② 上記で得られた、全行の秒数の平均値を算出
③ 上記で得られた平均値をエポック秒として日時を作る。
④ 上記で作成した日時の時刻部分が、求めたい平均としての時刻になる。
以下は上記の考え方によるコードです。
python3
1
2timestamps = dfres['登録時刻'].apply(lambda dt: dt.replace(year=1970, month=1, day=1).timestamp()) # ①
3
4avg_timestamp = round(timestamps.mean()) # ②
5
6avg_date = datetime.datetime.fromtimestamp(avg_timestamp).astimezone(datetime.timezone.utc) # ③
7
8print(avg_date.time()) # ④
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/02/13 04:19