Pandas按CustomerID分组后根据churned值选最后或倒数第二行
报错原因
x['churned']返回的是当前分组下所有行的churned值组成的Series对象,无法直接和整数做布尔比较,因此触发了歧义错误。由于同一客户的churned取值完全一致,只需提取分组内任意一个churned标量值即可做判断。
正确实现
方法1:修正原lambda写法
对原有代码的判断逻辑做小幅调整即可运行:
df = df.groupby(['CustomerID'], as_index=False).apply( lambda x: x.iloc[-2] if x['churned'].iloc[0] == 1 else x.iloc[-1] ).reset_index(drop=True)
此处通过.iloc[0]提取分组内第一个churned值作为判断依据,末尾的reset_index(drop=True)用于清理多余生成的索引列。
方法2:向量化高性能写法(适配大数据量)
groupby+apply在数据量较大时运行效率偏低,可通过分组编号+条件筛选的方式实现,性能提升明显:
# 对每个客户分组内的行倒序编号:最后一行编号为0,倒数第二行编号为1 df['row_rank'] = df.groupby('CustomerID').cumcount(ascending=False) # 按规则筛选目标行 df = df[ ((df['churned'] == 0) & (df['row_rank'] == 0)) | ((df['churned'] == 1) & (df['row_rank'] == 1)) ] # 删除辅助列并重置索引 df = df.drop('row_rank', axis=1).reset_index(drop=True)
边界注意事项
如果存在churned取值为1、但该客户仅对应1条观测记录的场景,直接取iloc[-2]会触发索引越界错误,可根据业务需求调整判断逻辑,比如修改为:
lambda x: x.iloc[-2] if x['churned'].iloc[0] == 1 and len(x)>=2 else x.iloc[-1]
内容的提问来源于stack exchange,提问作者Preben
相关产品推荐
相关产品推荐

