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

如何在不将时间设为索引的前提下用pandas between_time()生成时段列

问题描述

有一个包含秒级时间戳的DataFrame,已通过以下代码将时间转换为datetime类型并提取时间部分:

df["start"]   = pd.to_datetime(df["start"], unit='s')
df["time"]    = df["start"].dt.time

需要添加df["timeofday"]列存储时段字符串,对应规则:

  • 0:00 - 5:59 → night
  • 6:00 - 11:59 → morning
  • 12:00 - 17:59 → afternoon
  • 18:00 - 21:59 → evening
  • 22:00 - 23:59 → night

尝试使用between_time()方法时,因要求索引为DatetimeIndex报错;修改索引后又出现赋值警告或错误,现寻求无需修改原索引的实现方法。

解决方案

方法一:使用pd.cut()按小时快速分段

利用start列的小时属性直接划分时段,无需修改原索引,效率较高:

import pandas as pd

# 定义时段区间与对应标签
bins = [-1, 5, 11, 17, 21, 23]
labels = ['night', 'morning', 'afternoon', 'evening', 'night']

# 生成timeofday列
df['timeofday'] = pd.cut(df['start'].dt.hour, bins=bins, labels=labels, include_lowest=True)

说明:include_lowest=True确保0点的小时数(0)被包含在第一个区间内,完美匹配时段规则。

方法二:使用np.select()自定义复杂条件

如果需要更灵活的时间判断(比如精确到分钟),可以用np.select()实现:

import numpy as np

# 定义各时段的判断条件
conditions = [
    (df['start'].dt.hour >= 0) & (df['start'].dt.hour <= 5),
    (df['start'].dt.hour >= 6) & (df['start'].dt.hour <= 11),
    (df['start'].dt.hour >= 12) & (df['start'].dt.hour <= 17),
    (df['start'].dt.hour >= 18) & (df['start'].dt.hour <= 21),
    (df['start'].dt.hour >= 22) & (df['start'].dt.hour <= 23)
]
# 对应条件的结果标签
choices = ['night', 'morning', 'afternoon', 'evening', 'night']

# 生成timeofday列
df['timeofday'] = np.select(conditions, choices, default='night')

说明:如果需要精确到分钟,可把条件改为(df['start'].dt.time >= pd.Timestamp('00:00').time()) & (df['start'].dt.time <= pd.Timestamp('05:59').time())这类形式,同样无需修改索引。

为什么之前的方法失效?

between_time()是Pandas针对DatetimeIndex设计的方法,必须将datetime类型列设为索引才能调用,但修改索引会破坏原DataFrame的结构,还容易引发SettingWithCopyWarning这类赋值警告。上述两种方法直接基于start列的属性进行判断,完全保留原索引结构,避免了这些问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:15:44