如何无需shift()辅助列筛选DataFrame中符合捐赠范围的连续行组?
解决方案:无需
shift()辅助列实现分组筛选 可以不使用shift()创建多列辅助列来实现需求,核心思路是按Member分组后,遍历每个组内的起始行,检查后续行是否满足捐赠额范围条件,筛选出符合行数要求的行组。
实现代码
1. 准备示例数据
import pandas as pd # 构造示例DataFrame data = [ ["05/02/2023", 1, 2], ["12/02/2023", 1, 2], ["19/02/2023", 1, 5], ["26/02/2023", 1, 2], ["05/03/2023", 1, 1.5], ["12/03/2023", 1, 2], ["19/03/2023", 1, 5], ["26/03/2023", 1, 5], ["05/02/2023", 2, 5], ["12/02/2023", 2, 5], ["19/02/2023", 2, 4.5], ["26/02/2023", 2, 5.1], ["05/03/2023", 2, 3], ["12/03/2023", 2, 3], ["19/03/2023", 2, 5], ["26/03/2023", 2, 5], ["05/02/2023", 3, 10], ["12/02/2023", 3, 11], ["19/02/2023", 3, 11], ["26/02/2023", 3, 12], ["05/03/2023", 3, 5], ["12/03/2023", 3, 10], ["19/03/2023", 3, 9], ["26/03/2023", 3, 9] ] df = pd.DataFrame(data, columns=["Date", "Member", "Donation"])
2. 定义分组筛选函数
def filter_valid_groups(group): valid_row_indices = [] group_length = len(group) # 遍历每个可能的起始行 for start_idx in range(group_length): initial_donation = group.iloc[start_idx]["Donation"] lower_bound = initial_donation * 0.8 upper_bound = initial_donation * 1.2 # 统计连续符合条件的行数 valid_count = 1 # 起始行本身算1行 for next_idx in range(start_idx + 1, group_length): if lower_bound <= group.iloc[next_idx]["Donation"] <= upper_bound: valid_count += 1 else: break # 遇到不符合的行,停止后续检查 # 满足行数要求(按示例调整为≥4,若严格按需求"至少5行"则改为≥5) if valid_count >= 4: # 把该连续有效组的所有行索引加入列表 valid_row_indices.extend(group.index[start_idx : start_idx + valid_count]) # 去重并按索引排序,避免重叠组的重复行 valid_row_indices = sorted(list(set(valid_row_indices))) return group.loc[valid_row_indices]
3. 应用函数并输出结果
# 按Member分组处理,然后重置索引 result_df = df.groupby("Member").apply(filter_valid_groups).reset_index(drop=True) print(result_df)
输出结果
Date Member Donation 0 05/02/2023 2 5.0 1 12/02/2023 2 5.0 2 19/02/2023 2 4.5 3 26/02/2023 2 5.1 4 05/02/2023 3 10.0 5 12/02/2023 3 11.0 6 19/02/2023 3 11.0 7 26/02/2023 3 12.0
逻辑说明
- 分组遍历:按
Member分组后,对每个组内的每一行作为起始行,计算其捐赠额的±20%上下限。 - 连续有效性检查:从起始行开始,依次检查后续行的捐赠额是否在上下限内,直到遇到不符合的行停止,统计连续有效行数。
- 筛选行组:若连续有效行数满足要求,则将该组的所有行索引加入有效列表,最后去重排序得到最终结果。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

