如何使用Pandas提取DataFrame中两个maintenance实例间的行数据
提取DataFrame中相邻'maintenance'之间的行
需求说明
有一个包含重复'maintenance'标识的DataFrame,需要提取每两个相邻'maintenance'实例之间的所有行,排除'maintenance'本身以及首尾未被两个'maintenance'包裹的行。
输入数据
name 0 process 0 name 1 maintenance name 2 process 2 name 3 process 3 name 4 process 4 name 5 process 5 name 6 maintenance name 7 process 7 name 8 process 8 name 9 process 9 name 10 maintenance name 11 process 11 name 12 process 12 name 13 process 13 name 14 process 14 name 15 maintenance
用户尝试的代码
用户尝试用循环实现,但无法确定终止条件:
for i in np.arange(len(df)-1): if df['process'][i] = 'maintenance': df['new'] = df[i]
目标输出
name 2 process 2 name 3 process 3 name 4 process 4 name 5 process 5 name 11 process 11 name 12 process 12 name 13 process 13 name 14 process 14
Pandas原生实现方案
利用Pandas的布尔标记和累加分组功能,无需循环即可实现:
步骤1:构造示例DataFrame(已有可跳过)
import pandas as pd data = { 'name': [f'name {i}' for i in range(16)], 'process': [ 'process 0', 'maintenance', 'process 2', 'process 3', 'process 4', 'process 5', 'maintenance', 'process 7', 'process 8', 'process 9', 'maintenance', 'process 11', 'process 12', 'process 13', 'process 14', 'maintenance' ] } df = pd.DataFrame(data)
步骤2:筛选目标行
# 标记所有 maintenance 行 mask = df['process'] == 'maintenance' # 生成分组编号:每遇到一次 maintenance,分组号加1 group_num = mask.cumsum() # 筛选条件:分组号为奇数(对应两个 maintenance 之间的区间)+ 不是 maintenance 行本身 result = df[(group_num % 2 == 1) & (~mask)] print(result)
结果验证
执行后输出与目标完全一致:
name process 2 name 2 process 2 3 name 3 process 3 4 name 4 process 4 5 name 5 process 5 11 name 11 process 11 12 name 12 process 12 13 name 13 process 13 14 name 14 process 14
原理说明
mask.cumsum()会给每个maintenance之后的行分配递增的分组号,第一个maintenance后的行分组号为1,第二个maintenance后的行分组号为2,以此类推。- 奇数分组号正好对应两个相邻
maintenance之间的区间(分组1对应第1、2个maintenance之间,分组3对应第3、4个maintenance之间),结合~mask排除maintenance行本身,即可精准提取目标数据。
内容的提问来源于stack exchange,提问作者Mitch
相关产品推荐
相关产品推荐

