Python/Pandas将字符串转换为时间(不包括日期)

43

我有一个Pandas数据框在Python 2.7中。

import pandas as pd
trial_num = [1,2,3,4,5]
sail_rem_time = ['11:33:11','16:29:05','09:37:56','21:43:31','17:42:06']
dfc = pd.DataFrame(zip(*[trial_num,sail_rem_time]),columns=['Temp_Reading','Time_of_Sail'])
print dfc

数据框如下所示:

  Temp_Reading Time_of_Sail
             1     11:33:11
             2     16:29:05
             3     09:37:56
             4     21:43:31
             5     17:42:06

这个数据框来自于一个*.csv文件。我使用Pandas将*.csv文件读入为一个Pandas数据框。当我使用print dfc.dtypes时,它告诉我列Time_of_Sail的数据类型是object。我想把这一列转换为datetime数据类型,但我仅想保留时间部分 - 我不需要年份、月份和日期。

我可以尝试这样做:

dfc['Time_of_Sail'] = pd.to_datetime(dfc['Time_of_Sail'])
dfc['Time_of_Sail'] = [time.time() for time in dfc['Time_of_Sail']]

但问题是,当我运行print dfc.dtypes时,它仍然显示列 Time_of_Sail object

有没有一种方法可以将此列转换为仅具有时间的datetime格式?

额外信息:

要创建上面的数据框和输出,也可以使用以下代码:

import pandas as pd
trial_num = [1,2,3,4,5]
sail_rem_time = ['11:33:11','16:29:05','09:37:56','21:43:31','17:42:06']
data = [
    [trial_num[0],sail_rem_time[0]],
    [trial_num[1],sail_rem_time[1]],[trial_num[2],sail_rem_time[2]],
    [trial_num[3],sail_rem_time[3]]
    ]
dfc = pd.DataFrame(data,columns=['Temp_Reading','Time_of_Sail'])
dfc['Time_of_Sail'] = pd.to_datetime(dfc['Time_of_Sail'])
dfc['Time_of_Sail'] = [time.time() for time in dfc['Time_of_Sail']]
print dfc
print dfc.dtypes

1
我正在使用Python 3.4,但是在复现您的问题时遇到了麻烦。当我尝试您建议的转换时,我发现dtype已更改为“datetime64 [ns]”。顺便说一句,您的数据框架构造对我不起作用,因为zip返回一个迭代器,该迭代器不被DataFrame构造函数接受。这可能是一个非常愚蠢的问题,但是您是否尝试运行您发布的确切代码? - user2027202827
是的,对我来说似乎正常工作。 - edesz
好的,我添加了另一种创建数据框和解决问题的方法。这可能会有所帮助 - 这种新方法对我来说似乎更加直观。 - edesz
这是因为据我所知,pandas没有单独的时间数据类型。在pandas中,对象类型映射到Python基本类型字符串。你想要实现什么?另外一件事是,在你编辑的示例中,你可以将zip()返回的迭代器作为list()的参数传递,而不是显式地创建列表,如list(zip([trial_num,sail_rem_time]))。这将返回一个DataFrame()期望的列表。 - user2027202827
让我们在聊天中继续这个讨论。点击此处进入聊天室 - user2027202827
显示剩余3条评论
6个回答

69

这两行:

dfc['Time_of_Sail'] = pd.to_datetime(dfc['Time_of_Sail'])
dfc['Time_of_Sail'] = [time.time() for time in dfc['Time_of_Sail']]

可以写成:

dfc['Time_of_Sail'] = pd.to_datetime(dfc['Time_of_Sail'],format= '%H:%M:%S' ).dt.time

谢谢。这解决了我的问题 - 我可以指定我需要的时间格式(没有日期)。 - edesz
4
请问 dt.time 是什么,它是做什么用的?我猜想这是从 datetime 模块中导入的。 - Nick Warke
这个操作能否进行“原地”修改? - tommy.carstensen
22
嗨,这会导致dtype变为对象而不是日期时间。 - Nikko
@Nikko 但是,如果您执行类似于 dfc[dfc['Time_of_Sail']>'17:00:00'] 的无效操作,则会出现错误 TypeError:'>'不支持'datetime.time'和'str'的实例之间的比较,因此我猜它是datetime,即使pandas只是说对象。奇怪的是,因为再次执行像dfc ['Time_of_Sail'] .dt.strftime('%H%M')这样的操作会导致错误AttributeError:仅能使用.datetimelike值的.dt访问器 - West

14

使用to_timedelta函数,我们可以将字符串转换为时间格式(timedelta64[ns]),通过指定单位例如秒、分钟等。

dfc['Time_of_Sail'] = pd.to_timedelta(dfc['Time_of_Sail'], unit='s')

2

看起来这个方法是行得通的:

dfc['Time_of_Sail'] = pd.to_datetime(dfc['Time_of_Sail'], format='%H:%M:%S' ).apply(pd.Timestamp)


注:该段代码为用Python语言处理时间数据的一种方法。

1
如果有人正在寻找更一般化的答案,请尝试。
dfc['Time_of_Sail']= pd.to_datetime(dfc['Time_of_Sail'])

0
如果您只想进行简单的转换,可以按照以下步骤操作:
import datetime as dt

dfc.Time_of_Sail = dfc.Time_of_Sail.astype(dt.datetime)

或者您可以在时间列中添加一个占位符字符串,然后使用 apply 函数进行转换:

dfc.Time_of_Sail = dfc.Time_of_Sail.apply(lambda x: '2016-01-01 ' + str(x))
dfc.Time_of_Sail = pd.to_datetime(dfc.Time_of_Sail).apply(lambda x: dt.datetime.time(x))

1
这对我没有用。不确定答案中是否只是一个旧版本,但我执行以下操作:df["Time"].astype(datetime.datetime) 时,我得到了 TypeError: dtype '<class 'datetime.datetime'>' not understood 的错误提示。 - Ramy

0

(已测试Python 3.10.9 / pandas 1.5.3)
您可以使用pd.to_datetime()datetime.timeSeries应用于apply()函数和dt访问器:dfc['Time_of_Sail'].apply(pd.to_datetime).dt.time

总结

import pandas as pd

# Original DataFrame
>>> dfc = pd.DataFrame(
>>>     {
>>>         'Temp_Reading': [1, 2, 3, 4, 5],
>>>         'Time_of_Sail': ['11:33:11', '16:29:05', '09:37:56', '21:43:31', '17:42:06']
>>>     }
>>> )

# Convert to datetime.time object
>>> dfc['Time_of_Sail'] = dfc['Time_of_Sail'].apply(pd.to_datetime).dt.time
>>> dfc['Time_of_Sail']
    0    11:33:11
    1    16:29:05
    2    09:37:56
    3    21:43:31
    4    17:42:06
    Name: Time_of_Sail, dtype: object

数据类型
实际上,dfc.dtypes 返回 Time_of_Sail object,但仔细查看后,您会发现它们是 datetime.time 对象:

>>> from pprint import pprint
>>> pprint([i for i in dfc['Time_of_Sail']])
[datetime.time(11, 33, 11),
 datetime.time(16, 29, 5),
 datetime.time(9, 37, 56),
 datetime.time(21, 43, 31),
 datetime.time(17, 42, 6)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接