根据另一列中的条件查找一列中唯一值的总数

时间:2019-01-18 11:04:02

标签: python pandas

我需要计算 ad_type 列中具有 sale 的唯一sender_id的数量。 ad_type 列具有三个值:租金共享销售

此计数与一些条件有关:

  1. 发件人ID 必须记录其他值,然后 sale 出现在 ad_type 列中,以包括在计数中,即 rental < / em>,租赁销售
  2. 如果 sender_id 仅记录了 sale ,并且在此之前没有其他值(即 sale ),则不应将其包括在计数中

要实现这一点,我想我可以标记满足条件的这些行,创建另一列,然后在该列上使用sum。

这就是我试图标记行的内容。

示例df:

sender_id     reply_date    ad_type     
1234          2016-05-16    sharing
1234          2017-06-20    sale
3333          2016-05-16    rental
3333          2016-06-20    sale
3333          2016-06-21    sale
6767          2016-05-16    sale
0101          2016-04-16    sale
0101          2016-04-17    sale
9999          2016-01-01    rental
9999          2017-01-19    sharing
9999          2018-04-17    sale

我在哪里尝试过

df['count'] = df['ad_type'].where(df['ad_type'] == 'sale')

并且:

df['count'] = df.groupby(level=0)['ad_type'].transform(lambda x: x == 'sale')

这个想法是,如果我可以在 count 列中正确设置此标记过程,那么我可以通过计算count列中有多少个yes来计数唯一的sender_id。

基于此尝试,生成的df应该如下所示:

sender_id     reply_date    ad_type    count    
1234          2016-05-16    sharing
1234          2017-06-20    sale       yes
3333          2016-05-16    rental
3333          2016-06-20    sale
3333          2016-06-21    sale       yes
6767          2016-05-16    sale
0101          2016-04-16    sale
0101          2016-04-17    sale
9999          2016-01-01    rental
9999          2017-01-19    sharing
9999          2018-04-17    sale       yes

对于我觉得这是一项复杂的任务,我们将不胜感激。

1 个答案:

答案 0 :(得分:1)

numpy.where&链接的3个布尔掩码按位使用AND

m = df['ad_type'] == 'sale'
#get groups with values before sale
vals = df.loc[m.groupby(df['sender_id']).cumsum() == 0, 'sender_id'].unique()
m1 = df['sender_id'].isin(vals)
#get last duplicated value per groups - for last sale
m2 = ~df.loc[m, 'sender_id'].duplicated(keep='last').reindex(df.index, fill_value=False)

df['count'] = np.where(m & m1 & m2, 'yes', '')
print (df)
    sender_id  reply_date  ad_type count
0        1234  2016-05-16  sharing      
1        1234  2017-06-20     sale   yes
2        3333  2016-05-16   rental      
3        3333  2016-06-20     sale      
4        3333  2016-06-21     sale   yes
5        6767  2016-05-16     sale      
6         101  2016-04-16     sale      
7         101  2016-04-17     sale      
8        9999  2016-01-01   rental      
9        9999  2017-01-19  sharing      
10       9999  2018-04-17     sale   yes