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

如何在Pandas DataFrame中找出连续0和1的重叠分组?

问题描述

有如下简单的DataFrame,包含二进制列status,以及可用于聚合的数值列column1和column2:

>>> df
   status  column1  column2
0       1       10        5
1       0       20        4
2       0       30        3
3       1       40        2
4       0       50        1
5       0       60        5
6       0       70        4
7       1       80        3
8       1       90        2
9       1      100        1
10      0      110        5

需要基于status列创建重叠分组:分组由1后跟0、0后跟1的状态切换点触发,形成的分组范围为(从索引0开始):索引0至2、索引2至3、索引3至6、索引6至9、索引9至10。

之后对分组后的数值列执行聚合操作:对column1求和,对column2求中位数,预期输出如下:

column1  column2
0     60.0      4.0
1     70.0      2.5
2    220.0      3.0
3    340.0      2.5
4    210.0      3.0

此前尝试过df['status'].diff().ne(x).cumsum()的多种变体,但无法处理重叠分组的场景。

解决方案

要实现这种重叠分组的聚合,可以通过定位状态切换点、生成分组索引对、逐个计算聚合值的步骤完成:

步骤1:定位状态切换点

找出status列中值发生变化的索引位置,这些位置就是分组的分界点:

# 获取status列发生变化的索引(跳过第一个元素,因为shift后第一个值为NaN)
switch_points = df['status'].diff().ne(0).iloc[1:].index.tolist()
# 补充起始索引和最后一行索引,形成完整的分界点列表
all_points = [0] + switch_points + [df.index[-1]]

步骤2:生成重叠分组的起止索引对

相邻分界点之间形成一个分组,且相邻分组共享分界点(实现重叠):

groups = [(all_points[i], all_points[i+1]) for i in range(len(all_points)-1)]

步骤3:计算分组聚合值

遍历每个分组,分别计算column1的和与column2的中位数,最后整理成结果DataFrame:

import pandas as pd

results = []
for start, end in groups:
    group_data = df.loc[start:end]
    sum_col1 = group_data['column1'].sum()
    median_col2 = group_data['column2'].median()
    results.append({'column1': sum_col1, 'column2': median_col2})

result_df = pd.DataFrame(results)
print(result_df)

运行代码后输出结果与预期一致:

column1  column2
0     60.0      4.0
1     70.0      2.5
2    220.0      3.0
3    340.0      2.5
4    210.0      3.0

简化实现

可以将步骤合并,用更简洁的代码完成:

# 获取所有状态切换点
switch_idx = df['status'].ne(df['status'].shift()).iloc[1:].index.tolist()
all_idx = [0] + switch_idx + [df.index[-1]]

# 直接生成聚合结果
result_df = pd.DataFrame([
    {
        'column1': df.loc[s:e, 'column1'].sum(),
        'column2': df.loc[s:e, 'column2'].median()
    } for s, e in zip(all_idx[:-1], all_idx[1:])
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 01:12:05