You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Pandas按天及列值阈值拆分DataFrame并计算时长与均值

优雅实现:Pandas原生方案处理按天拆分+连续数据块计算

嘿,这个需求完全可以用Pandas的原生分组、标记和聚合操作来搞定,不用依赖循环或者itertools.groupby,代码简洁又高效,我给你一步步拆解:

1. 先构造示例数据(方便你测试)

首先我们先模拟一个符合你描述的DataFrame,时间戳为索引,包含两列:

import pandas as pd
import numpy as np

# 生成时间戳索引(每15分钟一条数据)
timestamps = pd.date_range('2024-01-01 00:00', periods=100, freq='15T')
df = pd.DataFrame({
    'col1': np.random.randint(50, 100, size=100),  # 随机数值
    'col2': np.random.randint(60, 80, size=100)   # 包含低于70的数值,用于测试连续块
}, index=timestamps)

# 手动插入一些不满足col2≥70的行,模拟非连续的情况
df.loc[df.index[10:15], 'col2'] = 65
df.loc[df.index[30:35], 'col2'] = 62

2. 核心实现步骤

步骤1:标记连续满足条件的数据块

我们用布尔值累加的方式,给每个连续的col2≥70的数据块分配唯一ID:

# 当col2<70时,布尔值为True(即1),累加后会给每个连续满足条件的块分配相同ID
df['block_id'] = (df['col2'] < 70).cumsum()

原理:每次遇到不满足条件的行,block_id就会加1,这样连续满足条件的行就会共享同一个block_id,完美区分开不同的连续数据块。

步骤2:按日期+数据块分组,计算目标指标

先过滤出col2≥70的行,然后按日期(从索引提取)block_id分组,最后聚合计算时长和col1平均值:

# 分组聚合:计算每个连续块的时长和col1均值
result = df[df['col2'] >= 70].groupby([df.index.date, 'block_id']).agg(
    # 时长:索引的最大时间 - 最小时间
    duration=('index', lambda x: x.max() - x.min()),
    # col1平均值:直接用mean聚合
    col1_mean=('col1', 'mean')
).reset_index()

# 可选:如果不需要block_id列,可以删除
result = result.drop(columns='block_id')

3. 结果说明

最终的resultDataFrame会包含三列:

  • index:数据块所属的日期
  • duration:该连续数据块的时长(Timedelta类型,比如0 days 01:15:00
  • col1_mean:该数据块中col1的平均值

如果某个连续块只有一行数据,时长会显示为0 days 00:00:00,这符合逻辑(单个时间点没有时长)。

内容的提问来源于stack exchange,提问作者Joost

火山引擎 最新活动