Pandas如何筛选actual_Y为cancel的行及其前N行同用户数据
实现Pandas按分组取cancel行前N行的通用逻辑
默认你的数据已按每个user_id内的业务顺序(如示例中的id升序)完成排序,若你有专属时间排序字段可替换排序规则。
步骤1:构造测试数据
import pandas as pd # 示例数据构造 data = { 'id': [1,2,3,4,5,6,7,9], 'user_id': [10,10,10,15,15,88,88,99], 'actual_Y': ['renew','renew','cancel','renew','cancel','renew','renew','cancel'] } df = pd.DataFrame(data)
步骤2:通用筛选函数
def filter_cancel_and_pre_n(df, n): # 按user_id分组、组内按id升序排序,保证行顺序符合业务逻辑 df_sorted = df.sort_values(['user_id', 'id']).reset_index(drop=True) result = [] for user_id, group in df_sorted.groupby('user_id'): # 查找当前用户所有actual_Y为cancel的行的组内位置 cancel_pos_list = group[group['actual_Y'] == 'cancel'].index.tolist() if not cancel_pos_list: # 该用户无cancel行直接跳过 continue # 遍历每个cancel行,取对应前N行+cancel本身 for pos in cancel_pos_list: # 起始位置不能小于0 start = max(0, pos - n) # iloc切片左闭右开,所以结束位置取pos+1才能包含cancel行 target_rows = group.iloc[start:pos+1] result.append(target_rows) # 合并结果并去重,避免同用户多cancel行重复取相同行 final_df = pd.concat(result).drop_duplicates().reset_index(drop=True) return final_df
步骤3:效果测试
N=2测试
print(filter_cancel_and_pre_n(df, 2))
输出:
id user_id actual_Y 0 1 10 renew 1 2 10 renew 2 3 10 cancel 3 4 15 renew 4 5 15 cancel 5 9 99 cancel
N=1测试
print(filter_cancel_and_pre_n(df, 1))
输出:
id user_id actual_Y 0 2 10 renew 1 3 10 cancel 2 4 15 renew 3 5 15 cancel 4 9 99 cancel
内容的提问来源于stack exchange,提问作者Asad Khalil
相关产品推荐
相关产品推荐

