Подсчет повторного вхождения значения в python, агрегированного относительно другого значения - PullRequest
0 голосов
/ 29 августа 2018

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

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

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 три куки «A, B и D» снова возникли. Аналогичным образом для пользователя 2 "F и G" возникли снова. Я хочу объединить эти результаты следующим образом:

Sno User Reoccurred_Instances
 1   1    3
 2   2    2

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

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

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

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

РЕДАКТИРОВАТЬ: Как уже упоминалось в комментарии ниже, давайте предположим, что третий пользователь со значениями 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 голосов
/ 29 августа 2018

Выполните те же первые шаги, которые я предпринял в ответе на предыдущий вопрос, чтобы избавиться от последовательных 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 номер 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
...