Группировка данных Pandas
Есть датасет логов действий пользователей:
id,
сессия,
браузер,
действие
Я хочу сгруппировать данные по пользователям, но при этом для каждого действия Подтверждено, я хочу формировать отдельную цепочку данных и после действия Подтверждено начинаем новую цепочку и собираем в строчку все действия до следующего действия Подтверждено пользователя.
Как это можно сделать? Я так понимаю нужно использовать groupby(), но немного не понимаю механизм реализации такого запроса. По примерах тяжело сделать то что мне нужно в силу моего опыта.
Если я правильно понимаю, то на выходе мне нужно получить данные собранные в одну строчку для каждого действия Подтверждено для всех пользователей, и для повторных действия Подтверждено пользователя тоже.
Ответы (1 шт):
В общем случае, вы всегда можете "разрезать" датафрейм по определенному значению, а затем сделать группировку:
import pandas as pd
df = pd.DataFrame({"events":["e1", "e2", "approved", "e2", "e4", "e7", "approved", "e42"]})
events
0 e1
1 e2
2 approved
3 e2
4 e4
5 e7
6 approved
7 e42
df["grp"] = df["events"].eq("approved").cumsum().shift().bfill()
events grp
0 e1 0.0
1 e2 0.0
2 approved 0.0
3 e2 1.0
4 e4 1.0
5 e7 1.0
6 approved 1.0
7 e42 2.0
res = df.groupby("grp")["events"].apply(list)
print(res)
grp
0.0 [e1, e2, approved]
1.0 [e2, e4, e7, approved]
2.0 [e42]
Name: events, dtype: object
UPDATE:
import pandas as pd
df = pd.DataFrame({"events":["e1", "e2", "approved", "e2", "e4", "e7", "approved", "e42"],
"users":["user1", "user2", "user2", "user1", "user1", "user2", "user1", "user2"]})
events users
0 e1 user1
1 e2 user2
2 approved user2
3 e2 user1
4 e4 user1
5 e7 user2
6 approved user1
7 e42 user2
res = []
for i, g in df.groupby("users")[["events", "users"]]:
g["grp"] = g["events"].eq("approved").cumsum().shift().bfill()
res.append(({i:g.groupby("grp")["events"].apply(list).values.tolist()}))
print(res)
[{'user1': [['e1', 'e2', 'e4', 'approved']]}, {'user2': [['e2', 'approved'], ['e7', 'e42']]}]
UPDATE 2
import pandas as pd
df = pd.DataFrame({"events":["e1", "e2", "approved", "e2", "e4", "e7", "approved", "e42"],
"users":["user1", "user2", "user2", "user1", "user1", "user2", "user1", "user2"],
"attr1": [1, 2, 3, 4, 5, 6, 7, 8],
"attr2": [11, 22, 33, 44, 55, 66, 77, 88]
})
events users attr1 attr2
0 e1 user1 1 11
1 e2 user2 2 22
2 approved user2 3 33
3 e2 user1 4 44
4 e4 user1 5 55
5 e7 user2 6 66
6 approved user1 7 77
7 e42 user2 8 88
res = pd.DataFrame()
for i, g in df.groupby("users", as_index=False):
g["grp"] = g["events"].eq("approved").cumsum().shift().bfill()
res = pd.concat([res, g.groupby("grp")[["events", "attr1", "attr2", "users"]]
.agg({"events": list, "attr1":list, "attr2":list, "users":lambda x: list(x)[0]} )])
print(res)
events attr1 attr2 users
grp
0.0 [e1, e2, e4, approved] [1, 4, 5, 7] [11, 44, 55, 77] user1
0.0 [e2, approved] [2, 3] [22, 33] user2
1.0 [e7, e42] [6, 8] [66, 88] user2