Подсчет повторного появления значения в python, агрегированного относительно другого значения

1

Этот вопрос является продолжением этого вопроса, который я задал здесь:

Теперь у меня есть данные примерно так:

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

Есть ли более простой способ без использования цикла для получения этого результата.

Теги:
pandas
loops
logic
count

2 ответа

1
Лучший ответ

Следуя тем же первым шагам, что и в моем ответе на ваш предыдущий вопрос, чтобы избавиться от последовательных значений 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
  • 1
    Как всегда! Идеальная логика @sacul, так что прошло уже 2 года с тех пор, как я использую python, но такой уровень логики немного сложнее для меня. Не могли бы вы сказать мне, как я могу улучшить это?
  • 1
    Хочу добавить, что в результате выполнения вышеупомянутого запроса будут пропущены те пользователи, у которых нет повторного вхождения Cookie. Как я могу справиться с этим?
Показать ещё 10 комментариев
1

Другой подход к этому, который, я думаю, должен быть довольно гибким:

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.

  • 0
    Эй, ты отвечаешь замечательно, но есть одна проблема, с которой я сталкиваюсь. Допустим, есть пользователь C, у которого есть следующие файлы cookie: «H, H, H, J, J, J, J», поскольку повторного появления нет, если мы применим функцию сдвига, он оставит нас с «H, J "и будет считать это как 2, когда он должен был посчитать это как 0 в случае повторного появления. Возможно ли разместить это в коде?
  • 0
    Не уверен, что это проблема с этим; см. мое редактирование выше.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню