我这里有我正在尝试聚合的示例数据:
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"]
的计数
步骤是:
- 使用
groupby
根据“User”
列对数据集进行分组 使用
f
函数过滤所有行,仅选择第一个cat_1
出现之后的行。- 首先使用
reset_index
重置索引. - 使用
x[x["Category"].eq('cat_1')].index[0]
选择第一cat_1
行的索引 - 将
+1
添加到上一步骤的索引中,因为我们不需要cat_1
行。 - 使用
iloc
在步骤 2.3 定义的索引之前对行进行切片。
- 首先使用
删除多余的
User
索引reset_index
和drop=True
使用
groupby
根据User
和Category
列对数据帧进行分组使用
agg
聚合列并计算所有Ticket_id
。
这里我们有输出值。接下来的步骤是为了匹配所需的预期输出。
使用
rename
将count
输出重命名为count
.使用
assign
添加Category_1
列使用
set_index
将Category_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/