Python 将ISO 8601数据列转换为秒
我正在尝试将ISO 8601持续时间数据的pandas dataframe列转换为总秒数。持续时间值看起来像Python 将ISO 8601数据列转换为秒,python,pandas,duration,iso8601,isodate,Python,Pandas,Duration,Iso8601,Isodate,我正在尝试将ISO 8601持续时间数据的pandas dataframe列转换为总秒数。持续时间值看起来像PT7M7S,这意味着7分7秒。如果我使用类似于isodate.parse_duration(“PT7M7S”)的东西,那么isodate 0.5.4在解析一个字符串时是有效的。但是,我需要在pandas列上运行相同的命令,不知道如何运行。我尝试了isodate.parse_duration(df2['duration'])但它返回了TypeError:需要字符串 以下代码创建测试数据帧:
PT7M7S
,这意味着7分7秒。如果我使用类似于isodate.parse_duration(“PT7M7S”)的东西,那么isodate 0.5.4在解析一个字符串时是有效的。但是,我需要在pandas列上运行相同的命令,不知道如何运行。我尝试了isodate.parse_duration(df2['duration'])
但它返回了TypeError:需要字符串
以下代码创建测试数据帧:
这是我尝试过但无效的代码:
理想的输出是让列duration
包含对应于该行的总秒数。例如,第一行不是PT7M7S
,而是427
谢谢你的帮助。谢谢。您可以用它来解析字符串:
import numpy as np
import pandas as pd
df = pd.DataFrame({'duration': ["PT7M7S", "PT7M14S", "PT6M45S"]})
df[['minutes','seconds']] = df['duration'].str.extract(r'PT(\d+)M(\d+)S', expand=True).astype('int')
df['total_seconds'] = 60*df['minutes'] + df['seconds']
屈服
duration minutes seconds total_seconds
0 PT7M7S 7 7 427
1 PT7M14S 7 14 434
2 PT6M45S 6 45 405
以下是另一种解决方案:
In [53]: (pd.to_datetime(df['duration'], format='PT%MM%SS', errors='coerce') -
...: pd.to_datetime('1900-01-01')).dt.total_seconds()
...:
Out[53]:
0 427.0
1 434.0
2 405.0
Name: duration, dtype: float64
数据:
说明:
In [55]: pd.to_datetime(df['duration'], format='PT%MM%SS', errors='coerce')
Out[55]:
0 1900-01-01 00:07:07
1 1900-01-01 00:07:14
2 1900-01-01 00:06:45
Name: duration, dtype: datetime64[ns]
为什么不在序列上使用apply
函数df['duration']
,这会快得多
下面是一个代码示例
In [17]: df['duration'] = df['duration'].apply(isodate.parse_duration)
In [18]: df['duration'] = df['duration']/np.timedelta64(1, 's')
In [19]: df
duration
0 427.0
1 434.0
2 405.0
注意,这里有一个技巧:用datetime
或timedelta
对象除以np。timedelta64
使用不同的单位,可以得到该对象的单位数
顺便说一下,如果有NaN
或缺少值,则需要处理它们
另外,对于unutbu的回答,仅当您的数据仅包含'M'
和'S'
时才适用。因为可能是pnnynmnndtnnnmnns
希望这对您有用。dur=df2['duration'].apply(isodate.parse_duration)
应该可以工作,但是如果您有很多字符串要解析,只解析字符串来提取分和秒组件,然后对这些提取的值执行算术可能会更快谢谢!这确实把它放在了hh:mm:ss
格式中,而不是总秒数,但我可以处理它。我真的很感谢你的帮助。如果你想提交这个作为一个答案,我可以选择它作为接受的答案。谢谢你的答复。当我在这里提供的小样本数据框上运行它时,它工作得非常好,但出于某种原因,我在大约300行的较大数据集上得到了以下内容ValueError:无法将浮点NaN转换为整数
,这意味着df['duration']
中至少有一个字符串与正则表达式模式PT(\d+)M(\d?)S
不匹配。我们可以找出那些字符串使用的是什么df.loc[~df['duration'].str.contains(r'PT(\d+M(\d+S'))]
。
In [54]: df
Out[54]:
duration
0 PT7M7S
1 PT7M14S
2 PT6M45S
In [55]: pd.to_datetime(df['duration'], format='PT%MM%SS', errors='coerce')
Out[55]:
0 1900-01-01 00:07:07
1 1900-01-01 00:07:14
2 1900-01-01 00:06:45
Name: duration, dtype: datetime64[ns]
In [17]: df['duration'] = df['duration'].apply(isodate.parse_duration)
In [18]: df['duration'] = df['duration']/np.timedelta64(1, 's')
In [19]: df
duration
0 427.0
1 434.0
2 405.0