Этот вопрос является продолжением этого вопроса, который я задал здесь:
Теперь у меня есть данные примерно так:
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 файлов cookie для пользователей 1 'A, B, C, D, E'. Теперь я хочу подсчитать, если какой-либо cookie был повторно обнаружен после того, как был встречен новый файл cookie. Например, в приведенном выше примере cookie A встречается снова на 7-м месте, а затем и на 12-м месте. ПРИМЕЧАНИЕ. Мы не будем считать A на 2-м месте одновременно, но в позиции 7 и 12 мы увидели много новых файлов cookie, прежде чем снова увидеть A, поэтому считаем этот экземпляр. Так вот что я получу, если я запустил код, упомянутый в моем предыдущем сообщении:
Для пользователя 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
Есть ли более простой способ без использования цикла для получения этого результата.
Следуя тем же первым шагам, что и в моем ответе на ваш предыдущий вопрос, чтобы избавиться от последовательных значений Cookie
и найти дубликаты:
no_doubles = df[df.Cookie != df.Cookie.shift()]
no_doubles['dups'] = no_doubles.Cookie.duplicated()
Затем используйте groupby для группировки User
в подмножестве данных, которые действительно дублируются (no_doubles[no_doubles['dups']]
), и найдите количество уникальных Cookies
для каждого пользователя с помощью nunique
:
no_doubles[no_doubles['dups']].groupby('User')['Cookie'].nunique().reset_index()
Это возвращает:
User Cookie
0 1 3
1 2 2
Вы можете переименовать столбцы по желанию
[EDIT]:
Чтобы справиться с различными случаями, вы можете просто добавить к этой логике. Например, учитывая следующий фрейм данных без повторов в User
number 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
Другой подход к этому, который, я думаю, должен быть довольно гибким:
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())])
Это займет дубликаты с точки зрения User
и Cookie
, а затем сравним значения Cookie
со своими соседями. Наконец, добавьте столбец True
/False
соответствующий двум вышеупомянутым флагам. Используйте этот столбец для создания двух сводных таблиц, которые вы упомянули (result_1
и result_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
EDIT: Как уже упоминалось в комментарии ниже, допустим, что третий пользователь имеет значения Cookie H
, H
, H
, J
, J
, J
Как это:
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.