Восстановление последовательности событий по условию

Есть таблица следующего вида:

user_id source visit_time transact transact_Id
2122547835443026286 google_cpc 2017-07-12 22:36:07 UTC 0 Null
2122547835443026286 google_cpc 2017-07-12 22:36:07 UTC 0 Null
2122547835443026286 google_cpc 2017-07-12 22:36:07 UTC 0 Null
2122547835443026286 google_organic 2017-07-12 23:20:17 UTC 1 21423421
2122547835443026286 google_organic 2017-07-12 23:20:17 UTC 1 21423421
2122547835443026286 google_organic 2017-07-12 23:20:17 UTC 1 21423421

user_id - идентификатор пользователя source - канал привлечения visit_time - время посещения страницы transact - была или не была осуществлена транзакция (покупка)

Если пользователь совершает покупку, то у него transact становится = 1, это означает, что для этой строки нужно найти все предыдущие переходы до момента транзакции.

Если пользователь так и не совершил транзакцию, то у него в Touchpoint должно быть None.

Результат:

transact_Id Touchpoint
Null NaN
21423421 google_cpc > google_organic

Ответы (1 шт):

Автор решения: Алексей Р

Много непонятного в деталях. Для начала можно сделать так:

df = pd.DataFrame({'user_id': [2122547835443026286] * 6 + [2122547835443026300] * 6,
                   'source': ['google_cpc', 'google_cpc', 'yandex', 'google_organic', 'google_organic',
                              'google_organic'] + ['google_cpc', 'google_cpc', 'google_cpc', 'google_organic',
                                                   'google_organic',
                                                   'google_organic'],
                   'visit_time': ['2017-07-12 22:36:07 UTC', '2017-07-12 22:36:07 UTC',
                                  '2017-07-12 22:36:07 UTC', '2017-07-12 23:20:17 UTC',
                                  '2017-07-12 23:20:17 UTC', '2017-07-12 23:20:17 UTC'] * 2,
                   'transact': [0, 0, 0, 1, 1, 1] + [0] * 6,
                   'transact_Id': ['Null', 'Null', 'Null', '21423421', '21423421', '21423421'] + ['123456'] * 6})
df.visit_time = pd.to_datetime(df.visit_time)


def fun(x):
    if x.transact.any():
        return pd.Series([x.loc[x.transact.eq(1), 'transact_Id'].max(),
                          ' > '.join(dict.fromkeys(x.sort_values(['transact', 'visit_time']).source).keys())],
                         index=['transact_Id', 'Touchpoint'])
    return pd.Series([x.transact_Id.max(), None], index=['transact_Id', 'Touchpoint'])


df1 = df.groupby('user_id').apply(fun)
print(df1)
                    transact_Id                            Touchpoint
user_id                                                              
2122547835443026286    21423421  google_cpc > yandex > google_organic
2122547835443026300      123456                                  None
→ Ссылка