Вы можете попробовать:
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
group, удалить строки перед первым cat_1
значением категории - Вычислить
count
для каждого ["User", "Category"]
Шаги:
- Сгруппируйте набор данных по столбцу
"User"
, используя groupby
Отфильтруйте все строки, чтобы выбрать только строки после первого вхождения cat_1
с помощью функции f
.
- Сначала сбросьте индекс, используя
reset_index
. - Выберите индекс первой строки
cat_1
, используя x[x["Category"].eq('cat_1')].index[0]
- Добавить
+1
к индексу из предыдущего шага, так как нам не нужна строка cat_1
. - Использование
iloc
для нарезки строк перед индексом, определенным на шаге 2.3.
Удалите избыточный индекс User
с помощью reset_index
и drop=True
Сгруппируйте фрейм данных в столбцах User
и Category
с использованием groupby
Агрегировать столбцы с помощью agg
и подсчитать все Ticket_id
.
Здесь у нас есть выходные значения. Следующие шаги здесь, чтобы соответствовать желаемому ожидаемому результату .
Переименуйте вывод count
в count
, используя rename
.
Добавьте столбец Category_1
, используя assign
Установите столбец Category_1
в качестве индекса, используя set_index
с 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