Pandas - 使用read_csv读取时间

3

我需要读取一个csv文件,其中一列以HH:MM:SS格式存储了一天中的时间。我需要对这些时间进行比较,所以我的想法是使用datetime。日期信息在文件中不相关也不存在。

如果我像这样读取文件并解析日期:

import pandas as pd    
dateparse = lambda x: pd.datetime.strptime(x, '%H:%M:%S')
my_data = pd.read_csv(file_name, parse_dates=['Time'], date_parser=dateparse)
print(my_data.loc[0]['Time'])

我得到了1900-01-01 11:03:41。如何去掉日期和年份?我不需要它,也不会在输出文件中使用。
有没有一种方法将这一列读取为datetime.time格式?

我也尝试过:

my_data = pd.read_csv(file_name, parse_dates=['Time'], 
                     date_parser=lambda x: pd.to_datetime(x, format='%H:%M:%S'))

具有相同的结果。


被删除的答案表明,您可以使用dateparse = lambda x: pd.datetime.strptime(x, '%H:%M:%S').time()pd.to_datetime(x, format='%H:%M:%S').time()来实现此操作,但正如我所说,这会导致性能问题。个人而言,除非您只想要pandas的便利,否则不要在df中存储非numpy本机dtypes。 - EdChum
1个回答

2

如果您只想将输出修改为csv格式,您可以在to_csv中指定date_format

In[130]:    
df = pd.DataFrame({'date':[pd.datetime.strptime('11:03:41', '%H:%M:%S')]})
df.to_csv(date_format='%H:%M:%S')

Out[130]: ',date\n0,11:03:41\n'

我建议将数据保留为datetime64,因为它允许您对列执行矢量算术运算,如果存储为datetime.time对象,则会限制您的操作。

您始终可以添加其他列,作为datetime.timestr表示:

In[131]:
df['time'] = df['date'].dt.time
df['str_rep'] = df['date'].dt.strftime('%H:%M:%S')
df

Out[131]: 
                 date      time   str_rep
0 1900-01-01 11:03:41  11:03:41  11:03:41

为了证明我的观点:
In[136]:

df = pd.DataFrame({'date':pd.to_datetime(['11:03:41', '15:23:33'], format='%H:%M:%S').time})
df
Out[136]: 
       date
0  11:03:41
1  15:23:33

现在,如果我们进行算术运算:

df['date'].diff()

这将引发以下错误:

TypeError: unsupported operand type(s) for -: 'datetime.time' and 'datetime.time'

如果我们将dtype保持为datetime64,我们仍然可以执行算术和比较操作,因为日期都是相同的,它们会根据您正在做什么而被抵消:

In[138]:
df = pd.DataFrame({'date':pd.to_datetime(['11:03:41', '15:23:33'], format='%H:%M:%S')})
df

Out[138]: 
                 date
0 1900-01-01 11:03:41
1 1900-01-01 15:23:33

In[139]:
df.diff()

Out[139]: 
      date
0      NaT
1 04:19:52

更新

如果您真的想要 datetime.time,那么您可以修改您的lambda

dateparse = lambda x: pd.datetime.strptime(x, '%H:%M:%S').time()
my_data = pd.read_csv(file_name, parse_dates=['Time'], date_parser=dateparse)

或者这个也可以工作:
my_data = pd.read_csv(file_name, parse_dates=['Time'], 
                     date_parser=lambda x: pd.to_datetime(x, format='%H:%M:%S').time())

比较和一些算术操作可以工作,但它不像本机的datetime64类型那样灵活。


我可以像操作datetime一样比较datetime64格式的时间吗? - mezzanaccio
肯定会有效,因为所有日期都相同,任何relativedelta或差异都只会使用时间组件。 - EdChum
问题是我必须将这些时间与另一个来源的时间进行比较。然后处理携带着1900年1月1日信息的时间相当不方便,因为其他时间肯定没有这个信息。 - mezzanaccio
正如我所展示的,您可以在构建的datetime列上调用dt.time以生成仅包含时间的列,但比较和操作可能不是矢量化的。 - EdChum
我最终创建了一个额外的时间 datetime.time 格式的列,并在将数据写入输出文件之前删除了它。我仍然想知道是否以及如何能够直接使用 read_csv 以 datetime.time 格式读取时间。无论如何,这解决了我的问题,所以接受了回答,谢谢。 - mezzanaccio
1
正如我所说,你可以修改你的lambda函数 dateparse = lambda x: pd.datetime.strptime(x, '%H:%M:%S').time(),这将导入为 datetime.time 对象。 - EdChum

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