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
相关产品推荐
相关产品推荐

