我有以下数据框设置:
dic = {'customer_id': [102, 102, 105, 105, 110, 110, 111],
'product':['skateboard', 'skateboard', 'skateboard', 'skateboard', 'shoes', 'skateboard', 'skateboard'],
'brand': ['Vans', 'Converse', 'Vans', 'Converse', 'Converse','Converse', 'Vans'],
'membership': ['member', 'not-member', 'not-member', 'not-member', 'member','not-member', 'not-member']}
df = pd.DataFrame(dic)
要求:如果客户是任何品牌的“成员(member)”,我需要在 customer_id 和产品粒度中删除成员(member)“非成员(member)”的行。
例如,在上面的数据框中,我们删除了产品为“滑板”的客户“102”,其中成员(member)资格为“非成员(member)”,因为他们已经是某个品牌 (Vans) 的成员(member)。我们不会放弃105,因为他们不属于任何品牌。我们不会因为产品不同而掉110。
我的方法:首先制作一个唯一的 customer_id + 产品列表(例如:102_skateboard)。然后循环列表,然后过滤掉唯一客户-产品对上的数据帧,然后检查数据帧是否包含成员资格,如果为真,则删除非成员行。这给了我预期的输出,但我想知道是否有更好的方法来做到这一点。
df['customer_product'] = df['customer_id'].astype(str) + '_' + df['product']
unique_customer_product = df['customer_product'].unique()
for pair in unique_customer_product:
filtered_df = df[df['customer_product'] == pair]
if 'member' in filtered_df['membership'].values:
df = df.drop(df[(df.customer_product == pair) & (df.membership == 'not-member')].index)
最佳答案
创建一个辅助 bool 列is_member
,然后就可以非常直接地表达条件。
df['is_member'] = df.membership.eq('member')
drop_mask = (
~df['is_member']
& df.groupby(['customer_id', 'product'])['is_member'].transform('any')
)
df = df.loc[~drop_mask].reset_index(drop=True)
关于python - 如何根据多个条件删除行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74829420/