Условно сгруппированные панды CumCount - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть этот DataFrame:

    dic = {'users' : ['A','A','B','A','A','B','A','A','A','A','A','B','A'],
            'product' : [1,1,2,2,1,2,1,2,1,1,2,1,1],
            'action' : ['see', 'see', 'see', 'see', 'buy', 'buy', 'see', 'see', 'see', 'see', 'buy', 'buy', 'buy']
    }

df = pd.DataFrame(dic, columns=dic.keys())

df


users   product action
0   A   1   see
1   A   1   see
2   B   2   see
3   A   2   see
4   A   1   buy
5   B   2   buy
6   A   1   see
7   A   2   see
8   A   1   see
9   A   1   see
10  A   2   buy
11  B   1   buy
12  A   1   buy

Мне нужен столбец, который подсчитывает, сколько раз каждый пользователь видел продукт перед его покупкой.

Результат должен быть примерно таким:это:

dic = {'users' : ['A','A','B','A','A','B','A','A','A','A','A','B','A'],
        'product' : [1,1,2,2,1,2,1,2,1,1,2,1,1],
        'action' : ['see', 'see', 'see', 'see', 'buy', 'buy', 'see', 'see', 'see', 'see', 'buy', 'buy', 'buy'],
        'see_before_buy' : [1,2,1,1,2,1,1,2,2,3,2,0,3]
}

users   product action  see_before_buy
0   A   1   see 1
1   A   1   see 2
2   B   2   see 1
3   A   2   see 1
4   A   1   buy 2
5   B   2   buy 1
6   A   1   see 1
7   A   2   see 2
8   A   1   see 2
9   A   1   see 3
10  A   2   buy 2
11  B   1   buy 0
12  A   1   buy 3

Может ли кто-нибудь мне помочь?

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

Один из подходов:

Сначала получите все пользователи и продукты

users=list(df.users.unique())
products=list(df.products.unique())

Создать словарь для комбинации продуктов пользователя, который отслеживает, какой продукт видел каждый пользователь

see_dict={users[i]:{products[j]:0 for j in range(len(products))} for i in range(len(users))}

#{'A': {1: 0, 2: 0}, 'B': {1: 0, 2: 0}}

Инициализировать пустой столбец

df["see_before_buy"]=None

Теперь для каждой строки, если это действие просмотра, обновите словарь (приращение) и присвойте значение. Если это действие на покупку, назначьте только значение и сбросьте счетчик

for i in range(len(df)):
    user=df.loc[i,"users"]
    product=df.loc[i,"products"]
    if(df.loc[i,"action"]=="see"): #if the action is see
        see_dict[user][product]+=1 #increment the see dictionary
        df.loc[i,"see_before_buy"]=see_dict[user][product] #assign this value for this row
    else: #buy action
        df.loc[i,"see_before_buy"]=see_dict[user][product] #assign the current value
        see_dict[user][product]=0 #reset the counter

Выход

   users  products action  see_before_buy
0      A         1    see               1
1      A         1    see               2
2      B         2    see               1
3      A         2    see               1
4      A         1    buy               2
5      B         2    buy               1
6      A         1    see               1
7      A         2    see               2
8      A         1    see               2
9      A         1    see               3
10     A         2    buy               2
11     B         1    buy               0
12     A         1    buy               3
0 голосов
/ 10 сентября 2018

Вам может потребоваться создать дополнительный ключ для groupby, используя cumsum после shfit

addkey=df.groupby(['user','#product']).action.apply(lambda x : x.eq('buy').shift().fillna(0).cumsum())
df['seebefore']=df.action.eq('see').groupby([df.user,df['#product'],addkey]).cumsum()
df
Out[131]: 
    index user  #product action  seebefore
0       0    A         1    see        1.0
1       1    A         1    see        2.0
2       2    B         2    see        1.0
3       3    A         2    see        1.0
4       4    A         1    buy        2.0
5       5    B         2    buy        1.0
6       6    A         1    see        1.0
7       7    A         2    see        2.0
8       8    A         1    see        2.0
9       9    A         1    see        3.0
10     10    A         2    buy        2.0
11     11    B         1    buy        0.0
12     12    A         1    buy        3.0
...