【问题标题】:Count re-occurrence of a value in python aggregated with respect to another value计算python中一个值相对于另一个值的重新出现次数
【发布时间】:2019-02-04 14:43:15
【问题描述】:

这个问题是我问here的这个问题的延续:

现在我有这样的数据:

Sno   User  Cookie
 1     1       A
 2     1       A
 3     1       A
 4     1       B
 5     1       C
 6     1       D
 7     1       A
 8     1       B
 9     1       D
 10    1       E
 11    1       D
 12    1       A
 13    2       F
 14    2       G
 15    2       F
 16    2       G
 17    2       H
 18    2       H

假设我们有 5 个用于用户 1“A、B、C、D、E”的 cookie。现在我想计算在遇到新 cookie 后是否再次出现任何 cookie。例如,在上面的示例中,cookie A 再次出现在第 7 位,然后也在第 12 位。注意我们不会同时计算 A 在第 2 位,但在第 7 位和第 12 位我们在再次看到 A 之前已经看到了许多新的 cookie,因此我们计算了那个实例。如果我运行previous post 中提到的代码,这就是我将得到的结果:

对于用户 1

Sno Cookie  Count
 1    A     2
 2    B     1
 3    C     0
 4    D     2
 5    E     0

对于用户 2

Sno Cookie  Count
 6    F     1
 7    G     1
 8    H     0

现在是棘手的部分,现在我们通过计数知道,对于用户 1,三个 cookie“A、B 和 D”再次出现。类似地,对于用户 2,“F 和 G”再次出现。我想像这样聚合这些结果:

Sno User Reoccurred_Instances
 1   1    3
 2   2    2

有没有更简单的方法而不使用循环来获得这个结果。

【问题讨论】:

    标签: python pandas loops count logic


    【解决方案1】:

    按照我在回答您上一个问题时采取的相同第一步,删除连续的 Cookie 值并找到重复项:

    no_doubles = df[df.Cookie != df.Cookie.shift()]
    
    no_doubles['dups'] = no_doubles.Cookie.duplicated()
    

    然后使用 groupby 对确实重复的数据子集(no_doubles[no_doubles['dups']])按User 分组,并使用nunique 查找每个用户的唯一Cookies 数量:

    no_doubles[no_doubles['dups']].groupby('User')['Cookie'].nunique().reset_index()
    

    这会返回:

       User  Cookie
    0     1       3
    1     2       2
    

    您可以根据需要重命名列

    [编辑]

    要处理不同的情况,您只需添加此逻辑即可。例如,考虑以下在 User 编号 3 中没有重复的数据框:

    Sno   User  Cookie
     1     1       A
     2     1       A
     3     1       A
     4     1       B
     5     1       C
     6     1       D
     7     1       A
     8     1       B
     9     1       D
     10    1       E
     11    1       D
     12    1       A
     13    2       F
     14    2       G
     15    2       F
     16    2       G
     17    2       H
     18    2       H
     18    3       H
     18    3       I
     18    3       J
    

    你可以这样做:

    no_doubles = df[(df.Cookie != df.Cookie.shift()) | (df.User != df.User.shift())]
    
    no_doubles['dups'] = no_doubles.duplicated(['Cookie', 'User'])
    
    no_doubles.groupby('User').apply(lambda x: x[x.dups]['Cookie'].nunique()).to_frame('Reoccurred_Instances')
    

    获取:

          Reoccurred_Instances
    User                      
    1                        3
    2                        2
    3                        0
    

    【讨论】:

    • 一如既往!完美的逻辑。 @sacul,所以我使用 python 已经 2 年了,但是这样的逻辑水平对我来说有点难以应用。你能告诉我如何改进它吗?
    • 我想补充一点,上面查询的结果会丢失那些没有再次出现Cookie的用户。我该如何解决?
    • 我认为,当您试图一步一步地想出解决方案时,这类问题会变得难以应付……如果您将其分解为多个步骤,事情往往会更易于管理。那,看看所有pandas 函数,几乎总是有一个解决方案使用pandas 开发人员已经编写和矢量化的函数
    • 查看您不再出现的情况的更新(它也处理其他几个边缘情况)
    • 嘿,我遇到了一些错误。使用这个公式,例如用户没有 Reoccurred_Instances 但有 2 个 cookie 的情况也被计为 2,因为我们正在对 cookie 进行 groupby。例如,对于一个用户,没有重复出现的 cookie,但是有 2 个不同的 cookie(如果是 USER 3),我得到的值为 2,我想得到值 0,因为虽然它有 2 个不同的但没有再次出现那些。有可能吗?
    【解决方案2】:

    对此的另一种方法,我认为应该非常灵活:

    dups  = df.loc[:, ['User', 'Cookie']].duplicated()
    diffs = df.Cookie != df.Cookie.shift()
    flags = np.logical_and(dups, diffs)
    
    df['flag'] = flags
    
    result_1 = df.groupby(['User', 'Cookie'])['flag'].agg([('Count', sum)])
    result_2 = result_1.groupby('User')['Count'].agg([('Reoccurred_Instances', lambda x: (x > 0).sum())])
    

    它将根据UserCookie 获取重复项,然后将Cookie 值与它们的邻居进行比较。最后,附加一列True/False 对应于上述两个标志。使用该列创建您提到的两个汇总表(result_1result_2,如下所示)。

                 Count
    User Cookie       
    1    A         2.0
         B         1.0
         C         0.0
         D         2.0
         E         0.0
    2    F         1.0
         G         1.0
         H         0.0
    
          Reoccurred_Instances
    User                      
    1                      3.0
    2                      2.0
    

    编辑:正如下面评论中提到的,我们假设第三个用户的 Cookie 值为 HHHJJJ。像这样:

        Sno  User Cookie
    0     1     1      A
    1     2     1      A
    2     3     1      A
    3     4     1      B
    4     5     1      C
    5     6     1      D
    6     7     1      A
    7     8     1      B
    8     9     1      D
    9    10     1      E
    10   11     1      D
    11   12     1      A
    12   13     2      F
    13   14     2      G
    14   15     2      F
    15   16     2      G
    16   17     2      H
    17   18     2      H
    18   19     3      H
    19   20     3      H
    20   21     3      H
    21   22     3      J
    22   23     3      J
    23   24     3      J
    

    通过上面的代码运行,我们得到以下结果数据帧:

                 Count
    User Cookie       
    1    A         2.0
         B         1.0
         C         0.0
         D         2.0
         E         0.0
    2    F         1.0
         G         1.0
         H         0.0
    3    H         0.0
         J         0.0
    

    还有:

          Reoccurred_Instances
    User                      
    1                      3.0
    2                      2.0
    3                      0.0
    

    代码的设置方式仍然会显示第三个用户(没有任何重复的Cookie 值),Reoccurred_Instances 值为 0。

    【讨论】:

    • 嘿,你的回答很好,但我面临一个问题。假设有一个用户 C 有以下 cookie:“H,H,H,J,J,J,J”,因为没有重新出现,如果我们应用移位功能,它会给我们留下“H, J”,如果再次发生,应该将其计为 0 时将其计为 2。是否可以在代码中容纳这一点?
    • 不确定这是不是这个问题;见我上面的编辑。
    • 工作了,谢谢。我还有一个问题:stackoverflow.com/questions/52170493/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多