基于现有列创建Pandas新列:标记坐席通话可用性
坐席通话可用性标记的Pandas实现方案
问题背景
现有包含坐席通话数据的Pandas数据框df,包含start_time、end_time两个时间戳列,以及值为NaN的空白列availability,原始数据如下:
start_time end_time Availability 2023-02-07 08:00:11 2023-02-07 08:01:49 NaN 2023-02-07 08:00:24 2023-02-07 08:02:05 NaN 2023-02-07 08:01:56 2023-02-07 08:06:28 NaN 2023-02-07 08:01:42 2023-02-07 08:03:56 NaN 2023-02-07 08:02:03 2023-02-07 08:07:18 NaN 2023-02-07 08:02:12 2023-02-07 08:03:45 NaN 2023-02-07 08:03:54 2023-02-07 08:06:21 NaN 2023-02-07 08:04:54 2023-02-07 08:06:08 NaN
需要基于start_time与end_time的对比更新availability列,规则如下:
- 从
df['end_time'][0:last_index]与df['start_time'][1:last_index]开始对比,若start_time大于end_time,标记availability为Yes,否则为No; - 每次迭代仅对比
availability为No或NaN的记录,找到第一个符合条件的记录后停止后续对比; - 迭代逻辑:首次迭代将第一条
end_time与后续start_time对比,标记对应记录的availability;第二次迭代排除availability为Yes的记录,继续对比并标记。
实现方案
步骤说明
- 确保时间列是datetime类型,避免字符串对比出错;
- 循环处理未标记(
NaN)或标记为No的记录,每次取当前未处理的第一条记录,用其end_time与后续所有未处理记录的start_time对比; - 找到第一个满足
start_time > end_time的记录,标记其availability为Yes,其余参与对比的未处理记录标记为No; - 重复上述步骤直到没有可处理的记录。
代码实现
import pandas as pd # 确保时间列转换为datetime类型 df['start_time'] = pd.to_datetime(df['start_time']) df['end_time'] = pd.to_datetime(df['end_time']) df['availability'] = df['availability'].astype('object') # 适配字符串赋值 while True: # 筛选未处理(NaN或No)的记录索引 unprocessed_idx = df[(df['availability'].isna()) | (df['availability'] == 'No')].index if len(unprocessed_idx) <= 1: break # 只剩最后一条或无未处理记录时终止循环 # 取当前未处理的第一条记录 current_idx = unprocessed_idx[0] current_end = df.loc[current_idx, 'end_time'] # 后续未处理的记录索引 subsequent_idx = unprocessed_idx[1:] # 查找第一个满足start_time大于当前end_time的记录 match_mask = df.loc[subsequent_idx, 'start_time'] > current_end match_idx = subsequent_idx[match_mask].min() if match_mask.any() else None if match_idx is not None: # 标记匹配记录为Yes df.loc[match_idx, 'availability'] = 'Yes' # 标记当前记录到匹配记录之间的未处理记录为No between_idx = subsequent_idx[subsequent_idx < match_idx] df.loc[between_idx, 'availability'] = 'No' else: # 无匹配记录,标记所有后续未处理为No并终止循环 df.loc[subsequent_idx, 'availability'] = 'No' break
代码解释
- 先转换时间列为datetime类型,保证时间对比的准确性;
- 循环中每次筛选未处理记录,若只剩1条则终止循环;
- 取第一条未处理记录的结束时间,与后续未处理记录的开始时间对比;
- 找到第一个符合条件的记录后,标记其为
Yes,中间的未处理记录标记为No; - 若没有找到符合条件的记录,将所有后续未处理记录标记为
No并终止循环。
内容的提问来源于stack exchange,提问作者Bits
相关产品推荐
相关产品推荐

