Pandas添加客户未来4周下单标记列及代码全量运行错误修复
错误原因
你的代码全量运行返回全1,核心是两个问题:
- 周次筛选边界错误:条件写的
df.Week_No >= x.Week_No,会把当前行自身的订单统计进去,哪怕后续没有订单,当前行的订单值求和必然>=1,自然所有行都返回1。你要统计的是当前周之后的订单,应该用严格大于号>排除当前行。 - 列名匹配不一致:原始数据列名是带空格的
WEEK NO、CUSTOMER、ORDERS,代码里写的是Week_No、Customer、total_orders,小样本测试如果手动改了列名能跑通,全量数据如果没做列名统一,筛选条件会直接失效。
修正后的实现
首先先统一列名,避免空格、大小写导致的匹配错误:
df.columns = ['CUSTOMER', 'WEEK_NO', 'ORDERS']
如果数据量不大,可以直接修正apply逻辑:
df['FLAG'] = df.apply( lambda x: 1 if df.loc[ (df['CUSTOMER'] == x['CUSTOMER']) & (df['WEEK_NO'] > x['WEEK_NO']) & (df['WEEK_NO'] <= x['WEEK_NO'] + 4), 'ORDERS' ].sum() >= 1 else 0, axis=1 )
如果是全量大数据集,apply逐行遍历全表性能很差,推荐用分组处理的方式,性能会提升几十倍:
# 先按客户、周次排序 df = df.sort_values(['CUSTOMER', 'WEEK_NO']).reset_index(drop=True) def calc_flag(group): weeks = group['WEEK_NO'].values orders = group['ORDERS'].values res = [] for idx, curr_w in enumerate(weeks): # 只看当前行之后的记录 follow_weeks = weeks[idx+1:] follow_orders = orders[idx+1:] match_mask = (follow_weeks > curr_w) & (follow_weeks <= curr_w + 4) res.append(1 if follow_orders[match_mask].sum() >= 1 else 0) group['FLAG'] = res return group df = df.groupby('CUSTOMER', group_keys=False).apply(calc_flag)
运行后得到的结果和预期完全一致:
CUSTOMER WEEK_NO ORDERS FLAG 0 Ann 4 1 1 1 Ann 6 3 0 2 John 1 1 0 3 John 7 2 0
内容的提问来源于stack exchange,提问作者MaivishM
相关产品推荐
相关产品推荐

