python pandas 按照时间(h:m:s)条件对使用datetimeIndex或datetime类型列的数据进行筛选的方法

本文详细介绍如何使用Pandas库高效地筛选包含datetime类型数据的DataFrame。包括使用datetimeIndex进行精确时间点和时间段筛选,以及在非datetimeIndex情况下,利用datetime.time类型进行精确时间筛选的方法。
部署运行你感兴趣的模型镜像

神奇的pandas,越用越觉得有意思。
pandas的切片功能非常强大,对于包含datetime类型列的dataframe和使用datetimeIndex的Series,通过给定datetime形式的字符串('2019-07-26 08:00:00', '2019-07', '2019-07-26', '2019-07-26 08:00')即可进行日期时间的筛选。

BUT!

如果是想查找某个周期(年,月,周)内的特定时间(h: m: s)的数据(比如,查看一年之中每天的08:00的数据行),上面的切片式筛选就不适用了!
虽然还是会按照字符串判定时间,但是由于所查询的列是datetime类型数据,其中包含了date(年月日),还不会智能到自动去掉date,只按time来筛选,导致返回的结果肯定不是想要的。

那么,对于这个需求,可分两种情况进行解决:
(本文成文时,基于0.24.2版本pandas,验证通过)

一,要筛选的数据,使用datetimeIndex作为index。

index有两个方法,针对datetimeIndex。
一个是index.indexer_at_time(),提取指定时间的数据的行号:

按照datetimeIndex 取Series中指定的时间(h:m:s)的数据行号
locs = test.index.indexer_at_time('7:00:00')
print(locs)

输出符合条件的数据行号
>>> [ 28 124]
print(type(locs))
>>> <class 'numpy.ndarray'>

再用iloc方法,按行号提取指定时间的数据行
print(test.iloc[locs])
>>> 
                        VALUE
START_TIME                   
2019-07-22 07:00:00  24238.11
2019-07-23 07:00:00  21946.81

搞定
print(type(test.iloc[locs]))
输出>>> <class 'pandas.core.frame.DataFrame'>

另一个是index.indexer_between_time(),这个可以按给定时间段进行筛选,返回符合条件的行号。
具体参数是:indexer_between_time(start_time, end_time, include_start=True,include_end=True),起时间(string),止时间(string),包含起时间(True/False),包含止时间(True/False)。这里的包含起止时间可以按照查询时“是否左闭,是否右闭”去理解。

按照datetimeIndex 取Series中指定的时间段(包含起时间,不包含止时间)
start_time = '08:00:00'
end_time = '09:00:00'
locs2 = test.index.indexer_between_time(start_time, end_time, include_start=True,include_end=False)

返回的是符合条件的数据的行号
print(locs2)
>>> [ 32  33  34  35 128 129 130 131]
print(type(locs2))
>>> <class 'numpy.ndarray'>

搞定
print(test.iloc[locs2])
>>> 
                        VALUE
START_TIME                   
2019-07-22 08:00:00  31107.17
2019-07-22 08:15:00  27614.50
2019-07-22 08:30:00  30453.01
2019-07-22 08:45:00  30660.73
2019-07-23 08:00:00  28185.59
2019-07-23 08:15:00  28690.62
2019-07-23 08:30:00  29500.40
2019-07-23 08:45:00  30008.18

二,要筛选的数据,不使用datetimeIndex作为index,但是该DataFrame中有至少一个使用了datetime类型数据的列。

非datetimeIndex情况下的DataFrame,内含有datetime类型的列时,
可以按datetime.time类型的数据来对datetime column进行指定筛选和切片筛选。
这样就可以提取指定的“小时:分钟:秒”的数据行。
pandas的datetime类型column支持dt方法,于是datetime类型的列就可以按照.time == .time进行匹配。
(这里的dt其实就是datetime,datetime类型数据支持的.year, .month, .day, .time, .hour等,这里都支持)

用datetime.datetime.time方法创造一个datetime.time类型的数据
将字符串转换成time:datetime.datetime.strptime('time string', 'format string')
import datetime
print(datetime.datetime.strptime('08:00','%H:%M').time())
>>> 08:00:00
print(type(datetime.datetime.strptime('08:00','%H:%M').time()))
>>> datetime.time

注:df中,df['START_TIME']列的数据是datetime数据类型,下面df.START_TIME既是指向该列

用df.query方法(挺有意思,刚发现的)进行特定time的数据筛选
print(df.query('START_TIME.dt.time == datetime.datetime.strptime("08:00","%H:%M").time()'))

用df条件筛选进行特定time的数据筛选
print(df[df.START_TIME.dt.time == datetime.datetime.strptime("08:00","%H:%M").time()])

这两条命令的返回是一样的。
             START_TIME            END_TIME         NE_NAME     VALUE
32  2019-07-22 08:00:00 2019-07-22 08:15:00            baka  31107.17
128 2019-07-23 08:00:00 2019-07-23 08:15:00            baka  28185.59


想切片方式筛选的话,可以设定start_time和end_time,
start_time = datetime.datetime.strptime('16:00','%H:%M').time()
end_time = datetime.datetime.strptime('16:30','%H:%M').time()
ne_list = ['baka']
筛选出df['START_TIME']之中:大于等于start_time、小于等于end_time,以及df['NE_NAME']在ne_list列表中的所有数据
print(df[(df.START_TIME.dt.time >= start_time) & (df.START_TIME.dt.time <= end_time) & (df.NE_NAME.isin(ne_list))])
>>> 
             START_TIME            END_TIME         NE_NAME     VALUE
64  2019-07-22 16:00:00 2019-07-22 16:15:00            baka  28861.52
65  2019-07-22 16:15:00 2019-07-22 16:30:00            baka  28934.74
66  2019-07-22 16:30:00 2019-07-22 16:45:00            baka  29235.14
160 2019-07-23 16:00:00 2019-07-23 16:15:00            baka  26666.94
161 2019-07-23 16:15:00 2019-07-23 16:30:00            baka  28675.96
162 2019-07-23 16:30:00 2019-07-23 16:45:00            baka  28586.23


甚至可以搞一个time_list,也用.isin方法进行筛选,这样一次提取多个指定时间的数据非常方便。
比如把今年内,每天的上午915和下午115的数据都弄出来。
而且也可以做类似切片形式的按时间段提取,只要把想要时间段的时间数据全部添加到列表中即可。
(当然,如果数据的时间粒度已经细化到分、甚至秒的话,就有点不适用了,那样的话,写两个切片式条件,用 | 连接更好些。)
time_list = []
time_list.append(datetime.datetime.strptime("08:00","%H:%M").time())
time_list.append(datetime.datetime.strptime("09:15","%H:%M").time())
time_list.append(datetime.datetime.strptime("11:30","%H:%M").time())
time_list.append(datetime.datetime.strptime("13:45","%H:%M").time())
ne_list = ['baka']
print(df[(df.START_TIME.dt.time.isin(time_list)) & (df.NE_NAME.isin(ne_list))])
>>> 
             START_TIME            END_TIME         NE_NAME     VALUE
32  2019-07-22 08:00:00 2019-07-22 08:15:00            baka  31107.17
37  2019-07-22 09:15:00 2019-07-22 09:30:00            baka  31268.25
46  2019-07-22 11:30:00 2019-07-22 11:45:00            baka  29116.12
55  2019-07-22 13:45:00 2019-07-22 14:00:00            baka  24565.35
128 2019-07-23 08:00:00 2019-07-23 08:15:00            baka  28185.59
133 2019-07-23 09:15:00 2019-07-23 09:30:00            baka  30427.79
142 2019-07-23 11:30:00 2019-07-23 11:45:00            baka  28852.88
151 2019-07-23 13:45:00 2019-07-23 14:00:00            baka  24931.63

两个时间段
start_time = datetime.datetime.strptime('16:00','%H:%M').time()
end_time = datetime.datetime.strptime('16:30','%H:%M').time()
start_time1 = datetime.datetime.strptime('18:00','%H:%M').time()
end_time1 = datetime.datetime.strptime('18:30','%H:%M').time()
ne_list = ['baka']

两个切片式条件取或
print(df[ (((df.START_TIME.dt.time >= start_time) & (df.START_TIME.dt.time <= end_time)) | 
((df.START_TIME.dt.time >= start_time1) & (df.START_TIME.dt.time <= end_time1))) & 
(df.NE_NAME.isin(ne_list))]
)
>>> 
             START_TIME            END_TIME         NE_NAME     VALUE
64  2019-07-22 16:00:00 2019-07-22 16:15:00            baka  28861.52
65  2019-07-22 16:15:00 2019-07-22 16:30:00            baka  28934.74
66  2019-07-22 16:30:00 2019-07-22 16:45:00            baka  29235.14
72  2019-07-22 18:00:00 2019-07-22 18:15:00            baka  28193.47
73  2019-07-22 18:15:00 2019-07-22 18:30:00            baka  27489.57
74  2019-07-22 18:30:00 2019-07-22 18:45:00            baka  27459.55
160 2019-07-23 16:00:00 2019-07-23 16:15:00            baka  26666.94
161 2019-07-23 16:15:00 2019-07-23 16:30:00            baka  28675.96
162 2019-07-23 16:30:00 2019-07-23 16:45:00            baka  28586.23
168 2019-07-23 18:00:00 2019-07-23 18:15:00            baka  26940.09
169 2019-07-23 18:15:00 2019-07-23 18:30:00            baka  26536.41
170 2019-07-23 18:30:00 2019-07-23 18:45:00            baka  25966.47

题外:将datetime类型的列,搞一个只有time的Series出来,这样就能做到。

ts = df.START_TIME.dt.time
print(type(ts))
>>> <class 'pandas.core.series.Series'>
print(ts)
>>> 
0       00:00:00
1       00:15:00
2       00:30:00
          ...   
1533    23:15:00
1534    23:30:00
1535    23:45:00
Name: START_TIME, Length: 1536, dtype: object

以上。

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

<think>好的,用户的问题是如何使用Pandas筛选时间大于2018/5/4 0:05:00的数据。我需要结合他们提供的引用内容和之前的问题来回答。首先,用户提到的引用中,有关于Pandas按日期范围筛选数据的注意事项,比如使用&符号而不是and,以及如何将日期转换为DatetimeIndex。 首先,我需要确认用户的数据结构,比如日期是否已经是datetime类型。根据引用[2],正确的日期处理需要确保数据类型正确,可能需要使用pd.to_datetime进行转换。用户可能需要先将字符串日期转换为datetime对象,否则筛选可能无效。 然后,筛选条件。用户想要时间大于特定时间点,所以应该使用布尔索引。引用[1]提到,多个条件需要用&符号连接,并且不能使用and,这点需要注意。比如,当用户需要同时满足多个时间条件时,比如大于某个时间且小于另一个时间,就要用&。不过用户的问题只是单边条件,所以可能只需要df[df['date'] > '2018-05-04 00:05:00']。 另外,引用[3]提到关于日期的dt访问器,比如获取星期几,但这里可能不需要,除非用户需要更复杂的操作。但用户的问题比较简单,直接比较时间即可。 可能还需要考虑时区的问题,但用户没有提到,所以暂时可以忽略。同时,确保日期已经设置为索引的话,可以使用.loc进行更高效的筛选,如引用[2]中的例子,但用户的数据可能没有设置索引,所以需要根据情况处理。 用户可能遇到的常见问题包括日期格式不正确,者日期未正确转换为datetime类型,导致比较失败。因此,步骤中需要强调转换日期的重要性。 最后,给出示例代码,确保用户能直接复制使用。同时,考虑到用户可能想同时筛选时间范围,可以补充相关的例子,如添加结束时间使用&连接两个条件,如引用[4]中的多条件筛选方法。</think>### 分步说明Pandas筛选时间数据方法 --- #### 一、日期预处理(关键步骤) ```python import pandas as pd # 假设原始数据格式示例 data = { 'date': ['2018-05-03 23:55:00', '2018-05-04 00:06:00', '2018-05-04 09:30:00'], 'value': [100, 200, 300] } df = pd.DataFrame(data) # 转换为datetime类型(若未转换将无法正确比较时间) df['date'] = pd.to_datetime(df['date']) # 核心转换[^2] ``` --- #### 二、筛选时间大于指定值的三种方法 1. **基础布尔索引**(推荐) ```python target_time = '2018-05-04 00:05:00' filtered_df = df[df['date'] > target_time] # 自动识别时间格式[^2] ``` 2. **配合时间范围查询**(含起始时间) ```python # 同时筛选时间范围(大于A且小于B) start_time = '2018-05-04 00:05:00' end_time = '2018-05-04 23:59:59' filtered_df = df[(df['date'] > start_time) & (df['date'] <= end_time)] # 必须用 & 符号[^1] ``` 3. **索引加速查询**(数据量较大时适用) ```python # 设置日期为索引 df.set_index('date', inplace=True) # 转换为DatetimeIndex[^2] # 使用loc快速筛选 filtered_df = df.loc['2018-05-04 00:05:00':] # 包含起始时间 filtered_df = df.loc[target_time:] # 等价写法 ``` --- #### 三、结果验证 ```python print("筛选数据:") print(df) print("\n筛选数据:") print(filtered_df) ``` --- ### 关键注意事项 1. **时间格式一致性**:确保目标时间字符串与数据的格式匹配,例如`'2018/5/4 0:05:00'`和`'2018-05-04 00:05:00'`等价 2. **时区处理**:若数据含时区信息需统一时区(如`df['date'].dt.tz_localize('UTC')`) 3. **性能优化**:对千万级数据推荐先将日期设置为索引[^2] --- ### 常见错误解决方案 | 错误现象 | 原因 | 修复方法 | |---------|------|---------| | `TypeError: Invalid comparison` | 日期未转换为datetime类型 | 执行`df['date'] = pd.to_datetime(df['date'])` | | 筛选结果为空 | 时间格式不匹配 | 统一格式为`YYYY-MM-DD HH:MM:SS` | | 内存溢出 | 数据量过大 | 使用`df.query("date > @target_time")` | ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值