python - Pandas Groupby 对列的特定值进行分组

标签 python pandas pandas-groupby

我这里有我正在尝试聚合的示例数据:

Ticket ID   User    Date        Category
1926        a       1/1/2020    cat_7
1947        a       1/1/2020    cat_6
1901        c       1/2/2020    cat_7
1067        a       1/3/2020    cat_1
1683        a       1/4/2020    cat_3
1281        a       1/4/2020    cat_3
1561        a       1/5/2020    cat_5
1932        a       1/5/2020    cat_5
1234        c       1/5/2020    cat_6
1013        c       1/7/2020    cat_7
1575        b       1/9/2020    cat_8
1152        b       1/10/2020   cat_4
1235        c       1/10/2020   cat_7
1596        b       1/11/2020   cat_4
1523        c       1/11/2020   cat_1
1447        b       1/12/2020   cat_4
1576        b       1/12/2020   cat_5
1260        c       1/13/2020   cat_2
1556        b       1/15/2020   cat_5
1838        b       1/16/2020   cat_5
1182        b       1/17/2020   cat_5

进入此预期输出:

User    Category 1  Next Category   Count
a       cat_1       cat_3           2
                    cat_5           2
b       cat_1       cat_4           3
                    cat_5           4
c       cat_1       cat_2           1

我不确定是否可以从列中提取特定值并将其用于按 cat_1 之后发生的事件进行分组

我失败的尝试:

df.groupby(["User", "Category"])["Ticket ID"].count()

结果是:

User  Category    Count
a     cat_1       1
      cat_3       2
      cat_5       2
      cat_6       1
      cat_7       1
b     cat_1       1
      cat_4       3
      cat_5       4
c     cat_1       1
      cat_2       1
      cat_6       1
      cat_7       3
      cat_8       1

最佳答案

你可以尝试:

def f(x):
    x = x.reset_index(drop=True)
    return x.iloc[x[x["Category"].eq('cat_1')].index[0]+1:]

df.groupby("User")\
    .apply(f) \
    .reset_index(drop=True) \
    .groupby(["User", "Category"]) \
    .agg({"Ticket ID": "count"}) \
    .assign(Category_1="cat_1") \
    .set_index("Category_1", append=True)\
    .reorder_levels([0, 2, 1])

说明:

有两个主要步骤:

  • 对于每个 User 组,删除第一个 cat_1 类别值之前的行
  • 计算每个["User", "Category"]计数

步骤是:

  1. 使用 groupby 根据“User” 列对数据集进行分组
  2. 使用 f 函数过滤所有行,仅选择第一个 cat_1 出现之后的行。

    1. 首先使用 reset_index 重置索引.
    2. 使用 x[x["Category"].eq('cat_1')].index[0] 选择第一 cat_1 行的索引
    3. +1 添加到上一步骤的索引中,因为我们不需要 cat_1 行。
    4. 使用 iloc在步骤 2.3 定义的索引之前对行进行切片。
  3. 删除多余的 User 索引 reset_indexdrop=True

  4. 使用 groupby 根据 UserCategory 列对数据帧进行分组

  5. 使用 agg 聚合列并计算所有 Ticket_id

这里我们有输出值。接下来的步骤是为了匹配所需的预期输出

  • 使用 renamecount 输出重命名为 count .

  • 使用 assign 添加 Category_1

  • 使用 set_indexCategory_1 列设置为索引与 append=True

  • 使用 reorder_levels 对索引级别重新排序


  • 完整代码+插图

    def f(x):
        x = x.reset_index(drop=True)
        return x.iloc[x[x["Category"].eq('cat_1')].index[0]+1:]
    
    
    # Step 2
    print(df.groupby("User")
            .apply(f))
    #         Ticket ID User       Date Category
    # User
    # a    3       1683    a   1/4/2020    cat_3
    #      4       1281    a   1/4/2020    cat_3
    #      5       1561    a   1/5/2020    cat_5
    #      6       1932    a   1/5/2020    cat_5
    # b    1       1152    b  1/10/2020    cat_4
    #      2       1596    b  1/11/2020    cat_4
    #      3       1447    b  1/12/2020    cat_4
    #      4       1576    b  1/12/2020    cat_5
    #      5       1556    b  1/15/2020    cat_5
    #      6       1838    b  1/16/2020    cat_5
    #      7       1182    b  1/17/2020    cat_5
    # c    6       1260    c  1/13/2020    cat_2
    
    # Step 3
    print(df.groupby("User")
            .apply(f)
            .reset_index(drop=True))
    #     Ticket ID User       Date Category
    # 0        1683    a   1/4/2020    cat_3
    # 1        1281    a   1/4/2020    cat_3
    # 2        1561    a   1/5/2020    cat_5
    # 3        1932    a   1/5/2020    cat_5
    # 4        1152    b  1/10/2020    cat_4
    # 5        1596    b  1/11/2020    cat_4
    # 6        1447    b  1/12/2020    cat_4
    # 7        1576    b  1/12/2020    cat_5
    # 8        1556    b  1/15/2020    cat_5
    # 9        1838    b  1/16/2020    cat_5
    # 10       1182    b  1/17/2020    cat_5
    # 11       1260    c  1/13/2020    cat_2
    
    # Step 5
    print(df.groupby("User")
            .apply(f)
            .reset_index(drop=True)
            .groupby(["User", "Category"])
            .agg({"Ticket ID": "count"}))
    #                Ticket ID
    # User Category
    # a    cat_3             2
    #      cat_5             2
    # b    cat_4             3
    #      cat_5             4
    # c    cat_2             1
    
    # Step 6
    print(df.groupby("User")
            .apply(f)
            .reset_index(drop=True)
            .groupby(["User", "Category"])
            .agg({"Ticket ID": "count"})
            .rename(columns={"Ticket ID": "count"}))
    #                count
    # User Category
    # a    cat_3         2
    #      cat_5         2
    # b    cat_4         3
    #      cat_5         4
    # c    cat_2         1
    
    print(df.groupby("User")
            .apply(f)
            .reset_index(drop=True)
            .groupby(["User", "Category"])
            .agg({"Ticket ID": "count"})
            .rename(columns={"Ticket ID": "count"})
            .assign(Category_1="cat_1")
            .set_index("Category_1", append=True)
            .reorder_levels([0, 2, 1]))
    #                           count
    # User Category_1 Category
    # a    cat_1      cat_3         2
    #                 cat_5         2
    # b    cat_1      cat_4         3
    #                 cat_5         4
    # c    cat_1      cat_2         1
    #                count Category_1
    
    # Step 7
    print(df.groupby("User")
            .apply(f)
            .reset_index(drop=True)
            .groupby(["User", "Category"])
            .agg({"Ticket ID": "count"})
            .rename(columns={"Ticket ID": "count"})
            .assign(Category_1="cat_1"))
    # User Category
    # a    cat_3         2      cat_1
    #      cat_5         2      cat_1
    # b    cat_4         3      cat_1
    #      cat_5         4      cat_1
    # c    cat_2         1      cat_1
    #                           count
    
    # Step 8
    print(df.groupby("User")
            .apply(f)
            .reset_index(drop=True)
            .groupby(["User", "Category"])
            .agg({"Ticket ID": "count"})
            .rename(columns={"Ticket ID": "count"})
            .assign(Category_1="cat_1")
            .set_index("Category_1", append=True))
    # User Category Category_1
    # a    cat_3    cat_1           2
    #      cat_5    cat_1           2
    # b    cat_4    cat_1           3
    #      cat_5    cat_1           4
    # c    cat_2    cat_1           1
    #                           count
    
    # Step 9
    print(df.groupby("User")
            .apply(f)
            .reset_index(drop=True)
            .groupby(["User", "Category"])
            .agg({"Ticket ID": "count"})
            .rename(columns={"Ticket ID": "count"})
            .assign(Category_1="cat_1")
            .set_index("Category_1", append=True)
            .reorder_levels([0, 2, 1]))
    # User Category_1 Category
    # a    cat_1      cat_3         2
    #                 cat_5         2
    # b    cat_1      cat_4         3
    #                 cat_5         4
    # c    cat_1      cat_2         1
    

    关于python - Pandas Groupby 对列的特定值进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61576749/

    相关文章:

    python-3.x - 用 Python 模拟 10,000 次硬币翻转非常慢

    python - 过滤和计算 Pandas 行的更快方法

    python - 用python计算现有库存

    python - 将 pandas DataFrame 中的行与另一个文本连接起来

    python - 使用 LSTM 基于其他列预测列的 future 结果

    python - 遍历一个大列表

    javascript - 使用pyjs : web browser won't read data from a txt file

    python - Pandas:日期时间索引系列到时间索引日期列数据框

    python - 使用 pandas 防止尾随零 "to_csv"

    python - pandas 将标题与行进行比较并删除重复的行