Python DataFrame按ID校验日维度列值递增规则的实现需求
解决方案:基于列索引的DataFrame日期列校验
需求回顾
给定首列为ID、其余列为日期型整数列的DataFrame,需按行执行以下校验并新增CHECK列:
- 若所有日期列值均为0 →
CHECK=0(无错误) - 非全0场景下,后一列值需满足:要么比前一列递增1,要么回0后后续列保持0或继续递增1;不满足则
CHECK=1 - 必须通过列索引而非列名实现逻辑
代码实现
import pandas as pd # 测试用示例DataFrame sample_data = { 'ID': [1, 2, 3, 4], '2023-01-01': [0, 1, 0, 2], '2023-01-02': [0, 2, 1, 3], '2023-01-03': [0, 0, 2, 2], '2023-01-04': [0, 1, 0, 0] } df = pd.DataFrame(sample_data) def validate_row(row): # 提取所有日期列的值(首列ID的索引为0,日期列从索引1开始) date_values = row[1:].values # 校验是否全为0 if (date_values == 0).all(): return 0 reset_triggered = False # 遍历日期列:从第2个日期列(索引2)开始,与前一列(索引i-1)对比 for col_idx in range(2, row.shape[0]): prev_val = row[col_idx - 1] curr_val = row[col_idx] if not reset_triggered: # 未触发回0时,允许两种情况:递增1 或 回0 if curr_val == prev_val + 1: continue elif curr_val == 0: reset_triggered = True continue else: # 不符合规则直接返回错误标记 return 1 else: # 已回0后,允许保持0 或 从当前值开始递增1 if curr_val == 0 or curr_val == prev_val + 1: continue else: return 1 # 所有列校验通过 return 0 # 应用校验逻辑到每一行,生成CHECK列 df['CHECK'] = df.apply(validate_row, axis=1)
关键逻辑说明
- 列索引定位:用
row[1:]直接获取所有日期列(无需依赖列名),通过range(2, row.shape[0])遍历后续日期列索引 - 全0校验:直接用
(date_values == 0).all()判断整行日期列是否全为0 - 状态标记:用
reset_triggered标记是否出现过回0操作,分别处理回0前后的校验规则:- 回0前:仅允许递增1或回0
- 回0后:允许保持0或从当前值继续递增1
- 提前终止:一旦发现不符合规则的列,立刻返回1,避免不必要的遍历
测试结果
运行上述代码后,示例DataFrame的CHECK列结果为:
| ID | 2023-01-01 | 2023-01-02 | 2023-01-03 | 2023-01-04 | CHECK |
|---|---|---|---|---|---|
| 1 | 0 | 0 | 0 | 0 | 0 |
| 2 | 1 | 2 | 0 | 1 | 0 |
| 3 | 0 | 1 | 2 | 0 | 0 |
| 4 | 2 | 3 | 2 | 0 | 1 |
内容的提问来源于stack exchange,提问作者diversis
相关产品推荐
相关产品推荐

