如何在Pandas中按客户分组后筛选未购酒客户的全部行?
问题描述
现有虚构客户消费数据,需筛选出**从未购买过酒精饮料(示例为Beer或Wine)**的客户的所有访问记录。已通过cumcount()为每位客户标记了访问次数,其中仅客户B080从未购买过酒精饮料,其余客户均有相关购买记录。需要用Pandas实现按客户分组后的精准筛选。
示例数据及预处理代码:
import pandas as pd df = pd.DataFrame({ "customer": ['A55', 'A55', 'A55', 'B080', 'B080', 'D900', 'D900', 'Z900', 'Z900', 'Z900', 'Z900'], "date": ['01/11/2016', '01/21/2016', '02/11/2016', '08/17/2016', '6/17/2016', '03/01/2016', '04/30/2016', '05/16/2016', '09/27/2016', '10/05/2016', '11/11/2016'], "item": ['Beer', 'Beer', 'Wine', 'Coffee', 'Gatorade', 'Wine', 'Coffee', 'Beer', 'Wine', 'Beer', 'Coffee'] }) # 标记每位客户的访问次数 df["customer_visit_number"] = df.groupby("customer").cumcount().add(1)
简便筛选方案
以下三种方法都能高效实现需求,可根据数据规模和个人习惯选择:
方法一:groupby.transform + 布尔索引
通过transform为每一行标记所属客户是否有过酒精购买记录,再反向筛选:
# 定义酒精饮料清单 alcohol_items = ['Beer', 'Wine'] # 为每行标记对应客户是否购买过酒精 has_alcohol_purchase = df.groupby('customer')['item'].transform(lambda x: x.isin(alcohol_items).any()) # 筛选从未购买酒精的客户所有记录 result = df[~has_alcohol_purchase]
方法二:先定位目标客户再提取记录
先找出所有从未购买酒精的客户ID,再从原数据中提取这些客户的全部行:
alcohol_items = ['Beer', 'Wine'] # 获取所有购买过酒精的客户ID集合 alcohol_customers = df[df['item'].isin(alcohol_items)]['customer'].unique() # 筛选不在酒精客户集合中的所有记录 result = df[~df['customer'].isin(alcohol_customers)]
这种方法在数据量较大时性能更优,因为先缩小了目标客户范围,减少后续匹配的计算量。
方法三:groupby.filter 直接过滤组
使用filter方法直接过滤掉存在酒精购买记录的客户组,代码最简洁直观:
alcohol_items = ['Beer', 'Wine'] # 过滤掉有过酒精购买的客户组,保留剩余客户的所有记录 result = df.groupby('customer').filter(lambda x: ~x['item'].isin(alcohol_items).any())
内容的提问来源于stack exchange,提问作者veg2020
相关产品推荐
相关产品推荐

