如何筛选DataFrame时间列指定时段并统计不同State值的数量?
解决方案:无需datetime索引也能统计指定时段的状态计数
不用纠结between_time必须依赖datetime索引的限制,这里有几种简单直接的方法可以实现你的需求:
方法1:直接对time列进行时间范围筛选
既然你的time列已经是datetime.time类型,我们可以直接和目标时间对象比较,筛选出符合时段的行后再统计:
import pandas as pd # 构造示例数据(和你的数据结构一致) data = pd.DataFrame({ 'State': ['Reply', 'Reply', 'Forward', 'Forward', 'Reply'], 'time': ['04:01:00', '08:04:00', '09:05:00', '12:06:00', '13:07:00'] }) # 转换time列为datetime.time类型(如果还没做的话) data['time'] = pd.to_datetime(data['time']).dt.time # 定义目标时段的起始和结束时间 start_time = pd.to_datetime('09:00:00').time() end_time = pd.to_datetime('13:00:00').time() # 筛选出9:00-13:00之间的行 filtered = data[(data['time'] >= start_time) & (data['time'] <= end_time)] # 统计两种状态的数量 state_counts = filtered['State'].value_counts() # 按照你想要的格式输出 print(f"(9:00:00至13:00:00)Forward = {state_counts.get('Forward', 0)},Reply = {state_counts.get('Reply', 0)}")
运行这段代码后,针对你的示例数据会输出:
(9:00:00至13:00:00)Forward = 2,Reply = 0
方法2:临时构建datetime索引使用between_time
如果你特别想用between_time方法,也可以临时给time列加一个任意日期(比如当天),拼接成完整的datetime后设置为索引,再调用方法:
import pandas as pd data = pd.DataFrame({ 'State': ['Reply', 'Reply', 'Forward', 'Forward', 'Reply'], 'time': ['04:01:00', '08:04:00', '09:05:00', '12:06:00', '13:07:00'] }) data['time'] = pd.to_datetime(data['time']).dt.time # 拼接日期和时间,生成datetime列 data['datetime'] = pd.to_datetime('2024-01-01 ' + data['time'].astype(str)) # 设置为索引 data = data.set_index('datetime') # 使用between_time筛选时段(include_end=False可以排除13:00:00整) filtered = data.between_time('09:00:00', '13:00:00') # 统计并输出 state_counts = filtered['State'].value_counts() print(f"(9:00:00至13:00:00)Forward = {state_counts.get('Forward', 0)},Reply = {state_counts.get('Reply', 0)}")
这个方法同样能得到和方法1一致的结果,好处是可以利用between_time的便捷性,而且日期不影响筛选(因为该方法只提取时间部分进行判断)。
小提示
- 如果你的需求是不包含13:00:00整,可以把方法1的条件改成
data['time'] < end_time,或者在方法2的between_time里添加include_end=False参数。 - 要是想确保两种状态都显示(哪怕数量为0),可以用
state_counts.reindex(['Forward', 'Reply'], fill_value=0)来补全计数。
内容的提问来源于stack exchange,提问作者Biyinzika
相关产品推荐
相关产品推荐

