You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas转换time列至time类型失效及时间过滤报错问题

问题解决:datetime.time列筛选报错及类型显示问题

问题场景

现有如下DataFrame:

site    date    time
1   AA  2018-01-01  0100
2   AA  2018-01-01  0200
3   AA  2018-01-01  0300
4   AA  2018-01-01  0400
5   AA  2018-01-01  0500
6   AA  2018-01-01  0600
7   AA  2018-01-01  0700
8   AA  2018-01-01  0800
9   AA  2018-01-01  0900

数据类型:

df.dtypes
>>> site            object
    date    datetime64[ns]
    time            object
    dtype: object

将time列转换为datetime.time类型后,列显示正常但仍为object类型:

df['time'] = df['time'].apply(lambda x: pd.to_datetime(x, format='%H%M').time())

转换后DataFrame:

site    date    time
1   AA  2018-01-01  01:00:00
2   AA  2018-01-01  02:00:00
3   AA  2018-01-01  03:00:00
4   AA  2018-01-01  04:00:00
5   AA  2018-01-01  05:00:00
6   AA  2018-01-01  06:00:00
7   AA  2018-01-01  07:00:00
8   AA  2018-01-01  08:00:00
9   AA  2018-01-01  09:00:00

但类型依旧是object:

df.dtypes
>>> site            object
    date    datetime64[ns]
    time            object
    dtype: object

单独查看值类型为datetime.time:

df.at[5,'time']
>>> datetime.time(5, 0)

type(df.at[5,'time'])
>>> datetime.time

使用between_time筛选时报错:

from datetime import time
df[df['time'].between_time(time(5),time(8))]
>>> TypeError: Index must be DatetimeIndex

解决方案

方案1:合并日期时间为DatetimeIndex(推荐)

between_time是针对DatetimeIndex设计的方法,无法直接用于普通列。可以把date和time合并成完整的datetime并设置为索引,再使用筛选方法:

# 合并date和time为完整datetime列
df['datetime'] = pd.to_datetime(df['date'].astype(str) + ' ' + df['time'].str.zfill(4).str[:2] + ':' + df['time'].str.zfill(4).str[2:])
# 设置为索引
df = df.set_index('datetime')
# 筛选5:00到8:00的数据
filtered_df = df.between_time('05:00', '08:00')

这种方式既能保留完整时间信息,又能正常使用between_time等时间相关工具方法。

方案2:直接对datetime.time列做比较筛选

如果不想修改索引,直接用datetime.time对象做范围比较即可:

from datetime import time
start_time = time(5)
end_time = time(8)
filtered_df = df[(df['time'] >= start_time) & (df['time'] <= end_time)]

该方法无需依赖索引,直接针对time列的datetime.time值做筛选,结果完全符合需求。

方案3:转换为timedelta类型(可选)

也可以将时间转换为timedelta类型,方便进行时间运算:

df['time_delta'] = pd.to_timedelta(df['time'].str.zfill(4).str[:2] + ':' + df['time'].str.zfill(4).str[2:] + ':00')
# 筛选5小时到8小时的时间段
filtered_df = df[(df['time_delta'] >= pd.Timedelta(hours=5)) & (df['time_delta'] <= pd.Timedelta(hours=8))]

类型显示为object的原因

Pandas没有专门的datetime.time数据类型,当列中存储Python原生datetime.time对象时,Pandas会将整列标记为object类型,这是正常现象,不影响值本身的类型和比较操作。

内容的提问来源于stack exchange,提问作者user88484

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:03:16