MySQL技术问询:基于二进制变量group_generator实现累加分组
实现按二进制变量累加值的分组需求
你的思路完全正确——通过计算当前行之前所有group_generator的累加值来生成分组ID,刚好能匹配你需要的分组规则。下面我会用两种常用工具(SQL和Python Pandas)来具体实现这个逻辑,验证结果是否符合预期。
需求回顾
先明确分组规则:当group_generator为1时,该组包含此前所有group_generator为0的行及当前行。示例数据和期望分组:
Numbers group_generator
10 0
20 0
30 1
40 0
50 1
60 1
期望分组:(10,20,30)、(40,50)、(60)
1. SQL实现方案
核心是用窗口函数计算当前行之前所有行的group_generator累加和,作为分组ID。如果是第一行,没有前置行,累加和默认为0。
代码示例
SELECT Numbers, group_generator, COALESCE(SUM(group_generator) OVER (ORDER BY Numbers ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), 0) AS group_id FROM your_table_name;
结果验证
执行后会得到:
| Numbers | group_generator | group_id |
|---|---|---|
| 10 | 0 | 0 |
| 20 | 0 | 0 |
| 30 | 1 | 0 |
| 40 | 0 | 1 |
| 50 | 1 | 1 |
| 60 | 1 | 2 |
这个group_id完全对应你的期望分组:group_id=0是第一组,group_id=1是第二组,group_id=2是第三组。
2. Python Pandas实现方案
在Pandas中,我们可以用cumsum()先计算累计和,然后通过位移(shift())来得到当前行之前的累加值,最后填充第一行的空值为0。
代码示例
import pandas as pd # 构造示例数据 data = { 'Numbers': [10, 20, 30, 40, 50, 60], 'group_generator': [0, 0, 1, 0, 1, 1] } df = pd.DataFrame(data) # 生成分组ID:计算当前行之前的group_generator累加和 df['group_id'] = df['group_generator'].cumsum().shift(fill_value=0) print(df)
结果输出
Numbers group_generator group_id 0 10 0 0.0 1 20 0 0.0 2 30 1 0.0 3 40 0 1.0 4 50 1 1.0 5 60 1 2.0
同样,group_id完美匹配你的分组需求,你可以用groupby('group_id')来对数据进行分组操作。
逻辑解释
为什么这个方法有效?
- 每遇到一个
group_generator=1,它会让后续行的分组ID加1,因为累计和会增加1,位移后就变成了新的分组ID。 - 所有在两个
1之间的0行,都会共享同一个分组ID,直到下一个1出现,完成一组的闭合。
内容的提问来源于stack exchange,提问作者Alexandr Kapshuk
相关产品推荐
相关产品推荐

