如何用Pandas根据时间范围为无表头DataFrame分配班次值
无表头CSV转DataFrame后实现班次列自动判断
现有读取代码
import pandas as pd path = r"data.csv" data = pd.read_csv(path, usecols=[0, 1, 3, 4], header=None) df = pd.DataFrame(data)
示例数据
{0: {0: '2022-08-06', 1: '2022-08-06', 2: '2022-08-06', 3: '2022-08-06', 4: '2022-08-06'}, 1: {0: '07:35:16', 1: '07:35:22', 2: '07:35:29', 3: '07:35:36', 4: '07:35:42'}, 3: {0: 'OK', 1: 'OK', 2: 'OK', 3: 'OK', 4: 'OK'}, 4: {0: 1.524, 1: 1.628, 2: 1.364, 3: 1.164, 4: 1.494}}
需求
需要添加ShiftID(班次)列并插入到索引2的位置,班次规则:
- 时间在 19:50:00 至 07:49:59 → 标记为
'PM' - 时间在 07:50:00 至 19:49:59 → 标记为
'AM'
尝试代码(存在问题)
ShiftID = pd.Series([], dtype=pd.StringDtype()) df[1] = pd.to_datetime(df[1]) start = datetime.strptime('19:50:00', '%H:%M:%S').time() end = datetime.strptime('07:49:59', '%H:%M:%S').time() for i in range(len(df)): if df[1].dt.time.between(start, end): # <------- 此处逻辑错误,无法处理跨天范围 ShiftID[i]= 'PM' else: ShiftID[i]= 'AM' df.insert(2, "ShiftID", ShiftID) display(df)
期望输出
{0: {0: '2022-08-06', 1: '2022-08-06', 2: '2022-08-06', 3: '2022-08-06', 4: '2022-08-06'}, 1: {0: '07:35:16', 1: '07:35:22', 2: '07:35:29', 3: '07:35:36', 4: '07:35:42'}, 2: {0: 'PM', 1: 'PM', 2: 'PM', 3: 'PM', 4: 'PM'}, 3: {0: 'OK', 1: 'OK', 2: 'OK', 3: 'OK', 4: 'OK'}, 4: {0: 1.524, 1: 1.628, 2: 1.364, 3: 1.164, 4: 1.494}}
解决方案
问题核心是between方法无法处理跨天的时间范围(起始时间晚于结束时间),需要拆分条件判断,同时用向量化操作替代循环提升效率:
import pandas as pd from datetime import datetime # 读取数据 path = r"data.csv" df = pd.read_csv(path, usecols=[0, 1, 3, 4], header=None) # 将时间列转为time类型 df[1] = pd.to_datetime(df[1], format='%H:%M:%S').dt.time # 定义班次时间阈值 pm_start = datetime.strptime('19:50:00', '%H:%M:%S').time() pm_end = datetime.strptime('07:49:59', '%H:%M:%S').time() # 向量化判断班次:时间>=19:50 或 <=07:49:59 标记为PM,否则为AM df['ShiftID'] = df[1].apply(lambda t: 'PM' if (t >= pm_start or t <= pm_end) else 'AM') # 将ShiftID列插入到索引2的位置 df.insert(2, 'ShiftID', df.pop('ShiftID')) # 查看结果 display(df)
关键说明
- 跨天范围处理:把
between替换为(t >= pm_start or t <= pm_end),直接匹配跨天的时间区间 - 向量化操作:用
apply替代循环,避免手动遍历索引,提升处理效率 - 时间类型转换:指定
format='%H:%M:%S'直接提取时间部分,避免自动补全日期
内容的提问来源于stack exchange,提问作者adi bahadur
相关产品推荐
相关产品推荐

