pandas如何提取值为TRUE的连续日期区间生成Attendance列
pandas 新增连续出勤记录列实现方案
- 核心逻辑:逐行提取值为
TRUE的日期,按日期列的顺序识别连续分段,单日直接输出日期,连续多日拼接为开始日期 - 结束日期格式,多段用逗号分隔。 - 完整实现代码如下:
import pandas as pd # 1. 构造示例数据集,替换为你的实际数据即可 df = pd.DataFrame({ 'Dt': ['san', 'don', 'sam', 'den'], '1/2/21': [True, True, False, False], '2/2/21': [True, True, True, False], '3/2/21': [True, False, True, True], '4/2/21': [True, True, False, False], '5/2/21': [True, True, True, True], '6/2/21': [True, True, True, True], '7/2/21': [True, True, True, False] }) # 提取所有日期列(排除首列人员标识Dt) date_columns = df.columns.drop('Dt').tolist() # 2. 定义单行出勤记录转换函数 def format_attendance(row): # 筛出当前行所有出勤为TRUE的日期 attend_dates = [d for d in date_columns if row[d]] if not attend_dates: return "" segments = [] current_start = attend_dates[0] # 遍历识别连续分段 for idx in range(1, len(attend_dates)): # 判断当前日期和上一个出勤日期是否在日期列中相邻 curr_pos = date_columns.index(attend_dates[idx]) prev_pos = date_columns.index(attend_dates[idx-1]) if curr_pos - prev_pos != 1: # 分段断开,保存上一段 current_end = attend_dates[idx-1] segments.append(current_start if current_start == current_end else f"{current_start} - {current_end}") current_start = attend_dates[idx] # 保存最后一个分段 current_end = attend_dates[-1] segments.append(current_start if current_start == current_end else f"{current_start} - {current_end}") return ",".join(segments) # 3. 生成Attendance列 df['Attendance'] = df.apply(format_attendance, axis=1)
- 运行后输出结果完全匹配需求:
| Dt | 1/2/21 | 2/2/21 | 3/2/21 | 4/2/21 | 5/2/21 | 6/2/21 | 7/2/21 | Attendance |
|---|---|---|---|---|---|---|---|---|
| san | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | 1/2/21 - 7/2/21 |
| don | TRUE | TRUE | FALSE | TRUE | TRUE | TRUE | TRUE | 1/2/21 - 2/2/21,4/2/21 - 7/2/21 |
| sam | FALSE | TRUE | TRUE | FALSE | TRUE | TRUE | TRUE | 2/2/21 - 3/2/21,5/2/21 - 7/2/21 |
| den | FALSE | FALSE | TRUE | FALSE | TRUE | TRUE | FALSE | 3/2/21,5/2/21 - 6/2/21 |
若需要调整连接符前后的空格、分隔符样式,直接修改函数内字符串拼接的格式即可。
内容的提问来源于stack exchange,提问作者Sanju M
相关产品推荐
相关产品推荐

