You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Pandas实现可变长度子数组列求和并扩展结果列

解决Pandas中按标记分段求和并提取起止时间的问题

问题场景

我正在尝试对DataFrame中的数据进行求和与整理,现有简化后的数据结构如下:

latitudelongitudetimet2mavkont
...46.51998-01-12 07:00:000.284698...0.001613
18.0...1998-01-24 08:00:00-1.304504...0.001418 FROMHERE
18.0...1998-01-24 09:00:00-1.113770...0.002679
18.0...1998-01-24 17:00:000.345001...0.004633 FROMHERE
18.0...1998-01-24 18:00:00-0.122498...0.004400
18.0...1998-01-24 19:00:000.041565...0.002184
18.0...1998-01-24 20:00:000.100861...0.002220
18.0...1998-01-24 21:00:000.120636...0.003083
18.0...1998-01-24 22:00:00-0.615662...0.004330
18.0...1998-01-24 23:00:00-0.686798...0.002404
18.0...1998-01-25 00:00:00-0.743134...0.000953
18.0...1998-01-29 02:00:00-4.786346...0.002984 FROMHERE

我的目标是对**FROMHERE标记之间**的av列数据求和,并添加time列中的起止日期(d1、d2),期望输出如下:

latitudelongitudet2m...kontsumd1d2
...46.50.284698...0.001613...1998-01-12 07:00:001998-01-24 08:00:00
18.0...-1.304504...FROMHERE0.0040971998-01-24 08:00:001998-01-24 09:00:00
18.0...0.345001...FROMHERE0.0242071998-01-24 17:00:001998-01-25 00:00:00
18.0...-4.786346...FROMHERExxxxxx1998-01-29 02:00:00...

我已尝试通过df.loc创建kont列来实现子数组求和,但陷入瓶颈。由于数据量庞大,希望采用Pandas原生向量化计算的解决方案,恳请提供帮助与思路。


解决方案(纯向量化,无循环)

这是典型的按标记分段聚合问题,完全可以用Pandas的分组聚合能力高效解决,全程避免循环,适配大数据量场景:

步骤1:提取标记并生成分组ID

首先我们需要把FROMHERE标记提取出来,然后用它生成唯一的分组ID,每个分组对应两个标记之间的区间:

# 1. 提取FROMHERE标记(假设标记在kont列末尾)
df['is_from_here'] = df['kont'].str.endswith('FROMHERE', na=False)
# 清理kont列的标记文本,还原原始数值
df['kont'] = df['kont'].str.replace(' FROMHERE', '', regex=False)

# 2. 生成分组ID:每次遇到FROMHERE就开启新分组
# 注意:第一个分组是从数据开头到第一个FROMHERE之前的部分
df['group_id'] = df['is_from_here'].cumsum()

步骤2:分组聚合计算核心指标

用groupby结合agg一次性计算每个分组的av求和、起止时间,全程向量化:

# 对每个分组聚合:sum_av是av列求和,d1是分组最早时间,d2是分组最晚时间
group_stats = df.groupby('group_id').agg(
    sum_av=('av', 'sum'),
    d1=('time', 'first'),
    d2=('time', 'last')
).reset_index()

步骤3:合并结果并整理格式

把聚合结果对应到每个FROMHERE行,同时处理开头的无标记分组:

# 1. 处理所有FROMHERE标记行,关联分组统计结果
result = df[df['is_from_here']].merge(group_stats, on='group_id', how='left')
# 把kont列替换为FROMHERE标记
result['kont'] = 'FROMHERE'

# 2. 处理开头的无标记分组(从数据起始到第一个FROMHERE)
first_group = df[df['group_id'] == 0]
if not first_group.empty:
    first_summary = pd.DataFrame({
        'latitude': [first_group['latitude'].iloc[0]],
        'longitude': [first_group['longitude'].iloc[0]],
        't2m': [first_group['t2m'].iloc[0]],
        'kont': [first_group['kont'].iloc[0]],
        'sum': [first_group['av'].sum()],
        'd1': [first_group['time'].iloc[0]],
        'd2': [first_group['time'].iloc[-1]]
    })
    # 合并到最终结果
    result = pd.concat([first_summary, result], ignore_index=True)

# 3. 处理最后一个分组的d2(如果没有后续数据,设为缺失值)
last_row_idx = result.index[-1]
if result.loc[last_row_idx, 'd1'] == result.loc[last_row_idx, 'd2']:
    result.loc[last_row_idx, 'd2'] = pd.NA

# 调整列顺序匹配期望输出
result = result[['latitude', 'longitude', 't2m', 'kont', 'sum', 'd1', 'd2']]

关键优势说明

  1. 纯向量化:全程使用Pandas原生分组聚合函数,没有逐行循环,处理百万级数据也能保持高效。
  2. 边界全覆盖:自动处理开头无标记分组、末尾未闭合分组的特殊情况,确保结果完整。
  3. 可扩展性:如果需要添加其他聚合指标(比如t2m的平均值),直接在agg里新增字段即可。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:40:24