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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

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

pandas

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

Q&A

解決済

2回答

3375閲覧

[python]24時間を超えた場合の扱いができずに困っています 例: 24:01:03

mini1988

総合スコア56

Python 3.x

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

pandas

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

0グッド

0クリップ

投稿2019/06/25 06:01

困っていること

データ行列内に時間が含まれているデータフレームがあります。
この時間の列に対して、
行間の差を時間(秒)で取得したいと考えており、
microsecondを含んでいる行もあることから
以下のコードを作成しました。

しかし、24時間を超えると、
例えば 24:01:03 とかになると、
以下のようなエラーが出てしまい、動作しません。

(※ 24を超えない他のデータセットだとうまく動作するのですが)

これを回避して、計算しつづけるような工夫をしたいのですが、
どなたか詳しい方、ご教授お願い致します。

データフレーム(時間)

[time] 0 1900-01-01 00:00:00 1 1900-01-01 00:00:15.984000 2 1900-01-01 00:00:17.971000 3 1900-01-01 00:00:19.958000 4 1900-01-01 00:00:20.995000 . . . 7516 37:12:07 7517 37:12:15 7518 37:12:20 7519 37:12:29 7520 37:12:35 7521 37:12:40 7522 37:12:44 Name:"time", Length:7522, dtype:object

書いたコード

time_data=[] for i in range(len(df)): cnt=0 try: df['time'][i] = pd.to_datetime(df['time'][i], format='%H:%M:%S') except: df['time'][i] = pd.to_datetime(df['time'][i], format='%H:%M:%S.%f') cnt+=df['time'][i].hour*60*60 cnt+=df['time'][i].minute*60 cnt+=df['time'][i].second time_data.append(cnt) df['timeX']=time_data

発生したエラー

ValueError: time data '24:01:03' does not match format '%H:%M:%S.%f' (match)

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

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

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

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

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

mather

2019/06/25 06:14

時刻だけを気にされているようですが、そういうときは日付も入れて datetime にするべきだと思います。
mini1988

2019/06/25 06:17

日付は重要ではなく、時間だけが大切な状況なのですが。24時間を超えて、そのまま値で扱いたいのですが、できないのでしょうか。
mather

2019/06/25 06:23

日付が重要ではないのはわかりますが、それを認め始めると24時以降いつまでをサポートすれば良いのかわかりませんから時刻フォーマットとしては認めない方針だと思います。
guest

回答2

0

ベストアンサー

結果として hours などの情報に分解して比較するだけなら正規表現で分解すれば良いと思います。

python

1import re 2 3s = "24:01:10" 4m = re.match(r"(\d+):(\d+):(\d+)", s) 5hours = int(m[1]) 6minutes = int(m[2]) 7seconds = int(m[3])

投稿2019/06/25 06:28

mather

総合スコア6753

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

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

mini1988

2019/06/25 06:44

おかげさまで解決することができました!ありがとうございました!
guest

0

まず、time行に microsecond を含んでいる行と含まない行が混在している件ですが、例外処理を使わなくとも単に pandas.to_datetime()format パラメータを 渡さなければ 解決するではないでしょうか。

更に、行いたい内容が

  • time列を Datetime型に変換
  • 行間の差を時間(秒)で取得したい

なのであれば、ループを使う必要は一切なく DataFrame.diff() を使って

Python

1# time列をDatetime型に変換 2df['time'] = pd.to_datetime(df['time']) 3# 行間の差を秒で求める 4df['diff'] = df['time'].diff().apply(lambda t:t.total_seconds())

とでもすると良い気がします。

で最後に、pandas.to_datetime() に 24時 を入力するとエラーとなる件ですが、これば何らかの文字列処理を行う必要がありますね・・。

とりあえず、下に時刻が '24'の箇所を'00' に置き換えて Datetime型に変換した後に 1日を追加するサンプルを書きましたので参考にしてみてください。

Python

1import pandas as pd 2 3df = pd.DataFrame({ 4 'time': ["2019-01-01 00:00:00", 5 "2019-01-01 12:00:00.100000", 6 "2019-01-01 22:30:00.100000", 7 "2019-01-01 24:01:00.100000", 8 ] 9}) 10 11# 前処理(時刻が'24'の箇所を'00'に置換) 12target = (df['time'].str[11:13] == '24') 13df.loc[target, 'time'] = df.loc[target, 'time'].str[:11] + '00' + df.loc[target, 'time'].str[13:] 14 15# Time列をDatetime型に変換 16df['time'] = pd.to_datetime(df['time']) 17 18# '24'を'00'に変換した箇所に 1日足す 19df.loc[target, 'time'] += pd.Timedelta(days=1) 20 21df['diff'] = df['time'].diff().apply(lambda t:t.total_seconds()) 22 23print(df) 24# time diff 25#0 2019-01-01 00:00:00.000 NaN 26#1 2019-01-01 12:00:00.100 43200.1 27#2 2019-01-01 22:30:00.100 37800.0 28#3 2019-01-02 00:01:00.100 5460.0

投稿2019/06/25 06:44

magichan

総合スコア15898

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

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

magichan

2019/06/25 06:45

あっ既に解決されてますね・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問