如何在DataFrame中筛选包含指定子串的起止行间数据
问题描述
需要从包含分段数据的DataFrame中,提取所有以包含Start子串的行为起始、包含End子串的行为结束的分段数据,保留每段的起止行及中间内容,过滤掉分段外的无关行。
原始DataFrame
+----------------------------------+---------+ | Col1 | Col2 | +----------------------------------+---------+ | Start A | 1 | | value 1 | 2 | | value 2 | 3 | | value 3 | 4 | | value 5 | 5 | | End A | 6 | | value 6 | 3 | | value 7 | 4 | | value 8 | 5 | | Start B | 1 | | value 1 | 2 | | value 2 | 3 | | value 3 | 4 | | value 5 | 5 | | End B | 6 | | value 6 | 3 | | value 7 | 4 | | value 8 | 5 | | Start C | 1 | | value 1 | 2 | | value 2 | 3 | | value 3 | 4 | | value 5 | 5 | | End C | 6 | +----------------------------------+---------+
预期结果
+----------------------------------+---------+ | Col1 | Col2 | +----------------------------------+---------+ | Start A | 1 | | value 1 | 2 | | value 2 | 3 | | value 3 | 4 | | value 5 | 5 | | End A | 6 | | Start B | 1 | | value 1 | 2 | | value 2 | 3 | | value 3 | 4 | | value 5 | 5 | | End B | 6 | | Start C | 1 | | value 1 | 2 | | value 2 | 3 | | value 3 | 4 | | value 5 | 5 | | End C | 6 | +----------------------------------+---------+
尝试过的代码及问题
尝试了以下代码:
m = df['To'].isin(['Start A', 'End A']).cumsum().eq(1) df[m|m.shift()]
存在两个问题:
- 仅返回第一组
Start A到End A的数据,无法处理多组分段; - 只能精确匹配指定字符串,无法通过子串
Start/End匹配所有分段。
解决方案
可以通过标记分段的起始和结束状态,结合累计计数来筛选所有目标分段:
实现代码
# 标记包含Start的行(分段起始) start_mask = df['Col1'].str.contains('Start') # 标记包含End的行(分段结束) end_mask = df['Col1'].str.contains('End') # 生成分段标识:每个Start对应一个新的分段ID segment_id = start_mask.cumsum() # 筛选处于有效分段内的行(已启动且未结束) valid_segment = segment_id != 0 # 合并条件:保留有效分段内的行 + 结束行本身 final_mask = valid_segment | end_mask # 获取最终结果 result_df = df[final_mask]
代码说明
str.contains用于匹配子串,解决了原代码只能精确匹配的限制;start_mask.cumsum()为每个Start生成递增的分段ID,确保多组分段都能被独立识别;valid_segment保留从Start到End之间的所有行,| end_mask确保End行本身被包含;- 自动过滤掉分段外的无关行,直接得到所有完整的
Start-End分段数据。
内容的提问来源于stack exchange,提问作者abhi
相关产品推荐
相关产品推荐

