如何用向量化方法计算Pandas列中连续满足条件的索引时长
时间序列中连续满足条件的时长计算:向量化优化方案
我有一份时间序列数据集,想要测量参数满足指定条件的持续时长。目前能遍历条件变化的位置来计算,但循环方法在大数据集下效率太低,求最佳的向量化实现方式。
示例数据集
import numpy as np import pandas as pd np.random.seed(0) # 生成数据集:24个月的月度数据,condition列是0/1随机值 df = pd.DataFrame({'condition': np.random.randint(0, 2, 24)}, index = pd.date_range(start='2020', freq='M', periods=24))
目标
新增一列duration,记录连续出现1的时长(即该连续段最后一个时间点减去第一个时间点),并将时长值对应到该连续段的最后一行。
当前实现(循环版,大数据集低效)
# 找出条件变化的起止位置 ends = df[df.condition.diff() < 0].index start = df[df.condition.diff() > 0].index[:ends.size] # 循环遍历起止点计算时长 for s, e in zip(start, ends): df.loc[e, 'duration'] = e - s # 偏移一行让时长对应到连续段的最后一行 df['duration'] = df.duration.shift(-1)
向量化优化方案(无循环,高效)
核心思路是用分组标记+组内聚合实现完全向量化计算,步骤如下:
- 给连续相同的
condition值标记唯一组ID - 筛选出
condition=1的组,计算每组的起止时间差 - 将计算结果映射回原DataFrame的对应位置
完整代码:
# 1. 生成连续值的组ID:每次condition变化时组ID+1 df['group_id'] = (df['condition'] != df['condition'].shift()).cumsum() # 2. 计算每个condition=1的组的持续时长:组内最后一个索引 - 第一个索引 group_durations = df[df['condition'] == 1].groupby('group_id').apply( lambda x: x.index[-1] - x.index[0] ) # 3. 将时长映射回原DataFrame,只给每组最后一行赋值 df['duration'] = df['group_id'].map(group_durations) # 可选:删除临时的group_id列 df.drop('group_id', axis=1, inplace=True)
优化说明
- 全程无循环,完全利用pandas/numpy的向量化运算,大数据集下速度比循环版快几个数量级
- 自动处理所有连续段,包括开头或结尾就是连续1的情况(原循环版可能漏处理边界)
- 时长值自动对应到连续段的最后一行,无需额外shift操作
内容的提问来源于stack exchange,提问作者n4321d
相关产品推荐
相关产品推荐

