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

如何为Pandas DataFrame的0/1序列生成groups分组列

实现Pandas DataFrame的自定义分组逻辑

我来帮你搞定这个自定义分组需求,咱们可以通过识别连续的1块,再结合区间划分来实现,逻辑清晰且容易维护。

步骤1:构造示例数据

首先先还原你的测试数据:

import pandas as pd

val_list = [0,0,1,1,1,0,0,0,0,1,1,0,1,1,1,1,0,0]
dd = pd.DataFrame({'val': val_list})

步骤2:识别所有连续的1块

我们需要先找出DataFrame中所有连续1的起始和结束索引,这是分组的核心锚点:

# 标记非1的位置,用于划分连续块
non_one = dd['val'] != 1
# 通过cumsum生成每个连续块的唯一ID
block_ids = non_one.cumsum()
# 筛选出所有包含1的块,提取每个块的起始和结束索引
one_blocks = dd[dd['val'] == 1].groupby(block_ids).agg(
    start=('val', 'idxmin'),
    end=('val', 'idxmax')
)

运行后one_blocks会得到所有连续1块的区间:

startend
124
3910
51215

步骤3:按规则分配分组标签

接下来我们根据这些1块的区间,给每个位置分配对应的组号或者ignore:

# 初始化groups列
dd['groups'] = ''

if not one_blocks.empty:
    # 处理第一个组:从开头到第一个1块的结束
    first_start, first_end = 0, one_blocks.iloc[0]['end']
    dd.loc[first_start:first_end, 'groups'] = 1

    # 处理中间的组:从上一个组结束的下一个位置到当前1块的结束
    for group_idx in range(1, len(one_blocks)):
        prev_block_end = one_blocks.iloc[group_idx-1]['end']
        curr_start = prev_block_end + 1
        curr_end = one_blocks.iloc[group_idx]['end']
        dd.loc[curr_start:curr_end, 'groups'] = group_idx + 1

    # 处理末尾的连续0:标记为ignore
    last_block_end = one_blocks.iloc[-1]['end']
    remaining_start = last_block_end + 1
    if remaining_start <= dd.index[-1]:
        # 确认剩余部分全是0(符合需求的标记条件)
        if dd.loc[remaining_start:, 'val'].sum() == 0:
            dd.loc[remaining_start:, 'groups'] = 'ignore'
else:
    # 如果DataFrame中没有1,所有位置都标记为ignore
    dd['groups'] = 'ignore'

验证结果

运行完上面的代码后,查看dd就会得到和你示例完全一致的结果:

print(dd)

输出:
val groups
0 0 1
1 0 1
2 1 1
3 1 1
4 1 1
5 0 2
6 0 2
7 0 2
8 0 2
9 1 2
10 1 2
11 0 3
12 1 3
13 1 3
14 1 3
15 1 3
16 0 ignore
17 0 ignore

这个方法的优势是逻辑清晰,基于连续块的划分来匹配你的需求,不管val序列多长都能稳定运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:17:26