将 ISO 8601 数据的 Pandas 列转换为秒
Convert Pandas Column of ISO 8601 Data to Seconds
我正在尝试将 ISO 8601 持续时间数据的 pandas 数据帧列转换为总秒数。持续时间值看起来像 PT7M7S
,这意味着 7 分 7 秒。如果我使用 isodate.parse_duration("PT7M7S")
之类的东西,isodate 0.5.4 可以有效地解析一个字符串。但是,我需要 运行 在 pandas 列上执行相同的命令,但不知道如何操作。我试过 isodate.parse_duration(df2['duration'])
但它 returns 一个 TypeError: Expecting a string
.
以下代码创建了一个测试数据帧:
df = ["PT7M7S", "PT7M14S", "PT6M45S"]
df = pd.DataFrame.from_dict(df)
names = df.columns.tolist()
names[names.index(0)] = 'duration'
df.columns = names
这是我试过但无效的代码:
import isodate
dur = isodate.parse_duration(df['duration'])
df['duration'] = dur.total_seconds()
理想的输出是让列 duration
包含对应于该行的总秒数。因此,例如,不是第一行 PT7M7S
而是 427
.
感谢任何帮助。谢谢。
您可以使用 str.extract
来解析字符串:
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 [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]
为什么不在系列 df['duration']
上使用 apply
函数,这样会快得多。
这是一个代码示例。
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'
的情况。因为 duration_isoformat
可能是 PnnYnnMnnDTnnHnnMnnS
.
希望这对你有用。
我正在尝试将 ISO 8601 持续时间数据的 pandas 数据帧列转换为总秒数。持续时间值看起来像 PT7M7S
,这意味着 7 分 7 秒。如果我使用 isodate.parse_duration("PT7M7S")
之类的东西,isodate 0.5.4 可以有效地解析一个字符串。但是,我需要 运行 在 pandas 列上执行相同的命令,但不知道如何操作。我试过 isodate.parse_duration(df2['duration'])
但它 returns 一个 TypeError: Expecting a string
.
以下代码创建了一个测试数据帧:
df = ["PT7M7S", "PT7M14S", "PT6M45S"]
df = pd.DataFrame.from_dict(df)
names = df.columns.tolist()
names[names.index(0)] = 'duration'
df.columns = names
这是我试过但无效的代码:
import isodate
dur = isodate.parse_duration(df['duration'])
df['duration'] = dur.total_seconds()
理想的输出是让列 duration
包含对应于该行的总秒数。因此,例如,不是第一行 PT7M7S
而是 427
.
感谢任何帮助。谢谢。
您可以使用 str.extract
来解析字符串:
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 [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]
为什么不在系列 df['duration']
上使用 apply
函数,这样会快得多。
这是一个代码示例。
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'
的情况。因为 duration_isoformat
可能是 PnnYnnMnnDTnnHnnMnnS
.
希望这对你有用。