teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

7

テキスト修正

2020/02/08 08:01

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -55,20 +55,21 @@
55
55
 
56
56
  考え方としては、
57
57
 
58
- - 所与のデータフレームの全行について、 `登録時刻`列の日時の日付部分を `1970-01-01` に置き換えた日時を作り、それらに対して `timestamp()` によってエポック秒を取得
58
+ 所与のデータフレームの全行について、 `登録時刻`列の日時の日付部分を `1970-01-01` に置き換えた日時を作り、それらに対して `timestamp()` によってエポック秒を取得
59
- - 上記で得られた、全行の秒数の平均値を算出
59
+ 上記で得られた、全行の秒数の平均値を算出
60
- - 上記で得られた平均値をエポック秒として日時を作る。
60
+ 上記で得られた平均値をエポック秒として日時を作る。
61
- - 上記で作成した日時の時刻部分が、求めたい平均としての時刻になる。
61
+ 上記で作成した日時の時刻部分が、求めたい平均としての時刻になる。
62
62
 
63
63
  以下は上記の考え方によるコードです。
64
64
  ```python3
65
- timestamps = dfres['登録時刻'].apply(lambda dt: dt.replace(year=1970, month=1, day=1).timestamp())
66
65
 
67
- avg_timestamp = round(timestamps.mean())
66
+ timestamps = dfres['登録時刻'].apply(lambda dt: dt.replace(year=1970, month=1, day=1).timestamp()) # ①
68
67
 
69
- avg_date = datetime.datetime.fromtimestamp(avg_timestamp).astimezone(datetime.timezone.utc)
68
+ avg_timestamp = round(timestamps.mean()) # ②
70
69
 
70
+ avg_date = datetime.datetime.fromtimestamp(avg_timestamp).astimezone(datetime.timezone.utc) # ③
71
+
71
- print(avg_date.time())
72
+ print(avg_date.time()) # ④
72
73
  ```
73
74
 
74
75
  - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/teratail-Q240153sample2](https://repl.it/@jun68ykt/teratail-Q240153sample2)

6

テキスト修正

2020/02/08 08:01

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -62,13 +62,13 @@
62
62
 
63
63
  以下は上記の考え方によるコードです。
64
64
  ```python3
65
- timestamps = [*map(lambda dt: dt.replace(year=1970, month=1, day=1).timestamp(), dfres['登録時刻'])]
65
+ timestamps = dfres['登録時刻'].apply(lambda dt: dt.replace(year=1970, month=1, day=1).timestamp())
66
66
 
67
- avg_second = round(np.mean(timestamps))
67
+ avg_timestamp = round(timestamps.mean())
68
68
 
69
- avg_date = datetime.datetime.fromtimestamp(avg_second).astimezone(datetime.timezone.utc)
69
+ avg_date = datetime.datetime.fromtimestamp(avg_timestamp).astimezone(datetime.timezone.utc)
70
70
 
71
71
  print(avg_date.time())
72
72
  ```
73
73
 
74
- - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/teratail-Q2401532](https://repl.it/@jun68ykt/teratail-Q2401532)
74
+ - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/teratail-Q240153sample2](https://repl.it/@jun68ykt/teratail-Q240153sample2)

5

テキスト修正

2020/02/08 07:58

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -71,4 +71,4 @@
71
71
  print(avg_date.time())
72
72
  ```
73
73
 
74
- - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/teratail-Q240153_2](https://repl.it/@jun68ykt/teratail-Q2401532)
74
+ - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/teratail-Q2401532](https://repl.it/@jun68ykt/teratail-Q2401532)

4

テキスト修正

2020/02/08 07:00

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -57,7 +57,8 @@
57
57
 
58
58
  - 所与のデータフレームの全行について、 `登録時刻`列の日時の日付部分を `1970-01-01` に置き換えた日時を作り、それらに対して `timestamp()` によってエポック秒を取得
59
59
  - 上記で得られた、全行の秒数の平均値を算出
60
+ - 上記で得られた平均値をエポック秒として日時を作る。
60
- - 上記で得られ平均値から日時を作れば、それの時刻部分が求めたい平均としての時刻になる。
61
+ - 上記で作成した日時の時刻部分が求めたい平均としての時刻になる。
61
62
 
62
63
  以下は上記の考え方によるコードです。
63
64
  ```python3

3

テキスト修正

2020/02/08 06:59

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -55,9 +55,9 @@
55
55
 
56
56
  考え方としては、
57
57
 
58
- - 所与のデータフレームの全行について、 `登録時刻`列の日時の日付部分を `1970-01-01` に置き換えた日時を作り、それに対して `timestamp()` によってエポック秒を取得
58
+ - 所与のデータフレームの全行について、 `登録時刻`列の日時の日付部分を `1970-01-01` に置き換えた日時を作り、それに対して `timestamp()` によってエポック秒を取得
59
- - 上記によって得られた、全行のエポック秒の平均を算出
59
+ - 上記得られた、全行の秒の平均を算出
60
- - 上記で得たエポック秒の平均値から日時を作れば、それの時刻部分が求めたい平均の時刻になる。
60
+ - 上記で得られた平均値から日時を作れば、それの時刻部分が求めたい平均としての時刻になる。
61
61
 
62
62
  以下は上記の考え方によるコードです。
63
63
  ```python3

2

テキスト修正

2020/02/08 06:55

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -46,4 +46,28 @@
46
46
  sec_to_time(dfres['時刻(秒)'].mean())
47
47
  ```
48
48
 
49
- - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/teratail-Q240153](https://repl.it/@jun68ykt/teratail-Q240153)
49
+ - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/teratail-Q240153](https://repl.it/@jun68ykt/teratail-Q240153)
50
+
51
+
52
+ ### 追記
53
+
54
+ 上記の回答コードは、補助的な関数の中で、`3600` や `60` という数字を使って、時刻オブジェクトと数値の変換を行っており、煩雑でした。これらを使わない方法を考えたので追記します。
55
+
56
+ 考え方としては、
57
+
58
+ - 所与のデータフレームの全行について、 `登録時刻`列の日時の日付部分を `1970-01-01` に置き換えた日時を作り、それに対して `timestamp()` によってエポック秒を取得
59
+ - 上記によって得られた、全行のエポック秒の平均を算出
60
+ - 上記で得たエポック秒の平均値から日時を作れば、それの時刻部分が求めたい平均の時刻になる。
61
+
62
+ 以下は上記の考え方によるコードです。
63
+ ```python3
64
+ timestamps = [*map(lambda dt: dt.replace(year=1970, month=1, day=1).timestamp(), dfres['登録時刻'])]
65
+
66
+ avg_second = round(np.mean(timestamps))
67
+
68
+ avg_date = datetime.datetime.fromtimestamp(avg_second).astimezone(datetime.timezone.utc)
69
+
70
+ print(avg_date.time())
71
+ ```
72
+
73
+ - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/teratail-Q240153_2](https://repl.it/@jun68ykt/teratail-Q2401532)

1

テキスト修正

2020/02/08 06:46

投稿

jun68ykt
jun68ykt

スコア9058

answer CHANGED
@@ -17,18 +17,18 @@
17
17
  return datetime.time(hour=h, minute=m, second=s)
18
18
 
19
19
 
20
- def time_to_sec(t):
20
+ def time_to_sec(dt):
21
21
  '''
22
- 引数 t で与えられるtimeオブジェクトの示す時、0時0分0秒から
22
+ 引数 dt で与えられるdatetimeオブジェクトの示す時の
23
- の経過秒数を返す
23
+ 時刻部分について、0時0分0秒からの経過秒数を返す
24
24
  '''
25
- return 3600 * t.hour + 60 * t.minute + t.second
25
+ return 3600 * dt.hour + 60 * dt.minute + dt.second
26
26
  ```
27
27
 
28
28
  上記の `time_to_sec` を使って、所与のデータフレームに、平均計算ののための一時的な列`時刻(秒)`を追加します。
29
29
 
30
30
  ```python3
31
- dfres.loc[:,'時刻(秒)'] = [*map(lambda t: time_to_sec(t), dfres['登録時刻'].dt.time)]
31
+ dfres.loc[:,'時刻(秒)'] = [*map(lambda t: time_to_sec(t), dfres['登録時刻'])]
32
32
  ```
33
33
 
34
34
  上記によって、データフレームに、下記のような `時刻(秒)`列が追加されます。
@@ -46,4 +46,4 @@
46
46
  sec_to_time(dfres['時刻(秒)'].mean())
47
47
  ```
48
48
 
49
- - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/Q240153](https://repl.it/@jun68ykt/Q240153)
49
+ - 動作確認用 Repl.it: [https://repl.it/@jun68ykt/teratail-Q240153](https://repl.it/@jun68ykt/teratail-Q240153)