如何用Pandas筛选DataFrame中每日特定时间窗口内的行?
筛选Pandas DataFrame中每日13:00-15:00的数据
问题描述
我有一个覆盖多天的样本数据集,所有数据均带有时间戳,希望筛选出每日13:00至15:00之间生成的行。以下是我的Pandas DataFrame样本数据:
22 22 2018-04-12T20:14:23Z 2018-04-12T21:14:23Z 0 6370.1 23 23 2018-04-12T21:14:23Z 2018-04-12T21:14:23Z 0 6368.8 24 24 2018-04-12T22:14:22Z 2018-04-13T01:14:23Z 0 6367.4 25 25 2018-04-12T23:14:22Z 2018-04-13T01:14:23Z 0 6365.8 26 26 2018-04-13T00:14:22Z 2018-04-13T01:14:23Z 0 6364.4 27 27 2018-04-13T01:14:22Z 2018-04-13T01:14:23Z 0 6362.7 28 28 2018-04-13T02:14:22Z 2018-04-13T05:14:22Z 0 6361.0 29 29 2018-04-13T03:14:22Z 2018-04-13T05:14:22Z 0 6359.3 .. ... ... ... ... ... 562 562 2018-05-05T08:13:21Z 2018-05-05T09:13:21Z 0 6300.9 563 563 2018-05-05T09:13:21Z 2018-05-05T09:13:21Z 0 6300.7 564 564 2018-05-05T10:13:14Z 2018-05-05T13:13:14Z 0 6300.2 565 565 2018-05-05T11:13:14Z 2018-05-05T13:13:14Z 0 6299.9 566 566 2018-05-05T12:13:14Z 2018-05-05T13:13:14Z 0 6299.6我需要忽略日期,仅评估时间部分来筛选数据。我可以通过遍历DataFrame循环判断时间,但肯定有更简便的方法。我已通过以下代码将原本为字符串类型的messageDate列转换为datetime类型:
df["messageDate"]=pd.to_datetime(df["messageDate"])但之后就卡在了如何仅按时间进行过滤的步骤,恳请各位提供解决方案。
解决方案
嗨,你已经搞定了最关键的一步——把字符串时间转成datetime类型,接下来完全不用写低效的循环,Pandas有现成的高效方法来筛选每日特定时间段的数据,给你两种实用方案:
方案一:直接比较时间对象(直观易懂)
这种方法逻辑清晰,适合快速实现:
- 导入Python的
datetime模块,定义你要筛选的时间范围 - 利用Pandas datetime列的
.dt.time属性提取纯时间部分,和定义好的时间对象做比较
import pandas as pd from datetime import time # 你已经完成的datetime转换步骤(这里再确认下) df["messageDate"] = pd.to_datetime(df["messageDate"]) # 定义筛选的时间区间:13:00 到 15:00 start_time = time(13, 0) end_time = time(15, 0) # 用布尔索引筛选符合条件的行 filtered_df = df[(df["messageDate"].dt.time >= start_time) & (df["messageDate"].dt.time <= end_time)]
方案二:基于小时/分钟的数值筛选(性能更优)
如果你的数据集很大,这种方法的执行效率会更高,因为它直接操作数值而非时间对象:
你可以把时间转换成总分钟数,或者直接组合小时和分钟的条件来筛选:
# 方法A:直接组合小时和分钟条件 filtered_df = df[ ((df["messageDate"].dt.hour == 13) & (df["messageDate"].dt.minute >= 0)) | (df["messageDate"].dt.hour == 14) | ((df["messageDate"].dt.hour == 15) & (df["messageDate"].dt.minute <= 0)) ] # 方法B:转换成总分钟数后筛选(更简洁) df["total_minutes"] = df["messageDate"].dt.hour * 60 + df["messageDate"].dt.minute filtered_df = df[(df["total_minutes"] >= 13*60) & (df["total_minutes"] <= 15*60)] # 如果不需要保留total_minutes列,可以删掉 # filtered_df = filtered_df.drop("total_minutes", axis=1)
验证筛选结果
你可以用下面的代码检查筛选出来的时间是否都在目标区间内:
print(filtered_df["messageDate"].dt.time.unique())
内容的提问来源于stack exchange,提问作者Hans van Schaick
相关产品推荐
相关产品推荐

