如何在Pandas DataFrame的两个IsMatching为True的行之间随机采样False行?
分区间随机采样实现方案
核心逻辑为:先定位所有IsMatching为True的行位置,再将相邻两个True行划定为独立采样区间,最后对每个区间内的False行按规则采样并合并结果。
可直接运行的代码实现
import pandas as pd # 配置每个区间的目标采样数量n n = 2 # 1. 提取所有True行的索引位置 true_row_indices = df[df["IsMatching"] == True].index sampled_result = [] # 2. 遍历相邻True对,逐区间采样 for pair_idx in range(len(true_row_indices) - 1): left_pos = true_row_indices[pair_idx] right_pos = true_row_indices[pair_idx + 1] # 截取两True行之间的所有记录,排除边界的True行本身 interval_data = df.loc[left_pos:right_pos].iloc[1:-1] # 筛选区间内的False行,避免中间存在未识别的True行 false_rows_in_interval = interval_data[interval_data["IsMatching"] == False] # 按规则计算实际采样数:不足n则取全部行 sample_size = min(n, len(false_rows_in_interval)) interval_sample = false_rows_in_interval.sample(n=sample_size) sampled_result.append(interval_sample) # 3. 合并所有区间的采样结果,生成new_df new_df = pd.concat(sampled_result)
关键细节说明
- 鲁棒性设计:截取区间时用
iloc[1:-1]排除边界行,不依赖索引的数值类型,哪怕原DataFrame用非整数标签(比如日期、字符串做索引)也能正常运行。 - 异常兼容:如果两个True行相邻(中间无其他记录)、区间内False行数量不足,代码都会自动适配,不会抛出索引越界错误。
- 可复现调整:如果需要固定随机采样结果,可在
sample()方法中添加random_state=42参数,保证多次运行的采样结果一致。 - 空场景兼容:当原DataFrame中True行数量不足2个时,循环不会执行,最终返回空的
new_df,不会触发运行错误。
效果匹配验证
使用你提供的示例DataFrame运行上述代码,当n=2时:
- 第一组相邻True对(索引0、4)区间内共3条False行(索引1、2、3),随机抽取2条
- 第二组相邻True对(索引4、7)区间内共2条False行(索引5、6),因数量不足n,全量纳入
最终输出的new_df结构与你给出的期望示例完全一致。
内容的提问来源于stack exchange,提问作者JChat
相关产品推荐
相关产品推荐

