如何根据Rolling_sum列的0值将Pandas dataframe拆分为多个子数据帧
问题背景
现有如下Pandas DataFrame构造代码:
import pandas as pd df = pd.DataFrame({'A':[4,5,0,0,5,0,0,4], 'B':[7,8,0,0,4,0,0,0], 'C':[1,3,0,0,7,0,0,0]}, columns = ['A','B','C']) df["sum"] = df.sum(axis=1) df["Rolling_sum"] = df["sum"].rolling(2, min_periods=1).sum()
运行后得到的原始DataFrame结构如下:
| 索引 | A | B | C | sum | Rolling_sum |
|---|---|---|---|---|---|
| 0 | 4 | 7 | 1 | 12 | 12.0 |
| 1 | 5 | 8 | 3 | 16 | 28.0 |
| 2 | 0 | 0 | 0 | 0 | 16.0 |
| 3 | 0 | 0 | 0 | 0 | 0.0 |
| 4 | 5 | 4 | 7 | 16 | 16.0 |
| 5 | 0 | 0 | 0 | 0 | 16.0 |
| 6 | 0 | 0 | 0 | 0 | 0.0 |
| 7 | 4 | 0 | 0 | 4 | 4.0 |
需求说明
需要根据Rolling_sum列的0值位置拆分原DataFrame,排除0值所在行,最终得到3个连续的子DataFrame:
- 子DataFrame1包含索引0-2的行
- 子DataFrame2包含索引4-5的行
- 子DataFrame3包含索引7的行
实现方案
核心逻辑是用0值行作为分割边界,给连续的非0值段分配独立分组号,再按分组号拆分:
# 1. 标记所有Rolling_sum为0的分割行 split_mask = df['Rolling_sum'] == 0 # 2. 给连续的非分割行分配唯一组号,每遇到一个分割行组号+1 df['group_id'] = split_mask.cumsum() # 3. 过滤掉分割行后按组号分组 grouped = df[~split_mask].groupby('group_id') # 4. 提取所有子DataFrame到列表,删掉辅助用的group_id列 sub_dfs = [group.drop(columns='group_id') for _, group in grouped]
结果验证
最终sub_dfs列表的三个元素就对应需求中的三个子DataFrame:
sub_dfs[0]对应第一个子数据帧sub_dfs[1]对应第二个子数据帧sub_dfs[2]对应第三个子数据帧
内容的提问来源于stack exchange,提问作者PPR
相关产品推荐
相关产品推荐

