Панды перебирают массивы с помощью groupby

Я загрузил CSV с 3 столбцами: метка времени, идентификатор пользователя и идентификатор кампании. У каждого пользователя есть> 1 идентификатор кампании с отметкой времени. Исходные данные выглядят следующим образом:

                   date    user_id           ad_campaign
0      2018-01-10 0:21:09  151312395      Search - Special
1      2018-01-10 0:21:19  151312395    Display - Branding
2      2018-01-10 0:21:32  151312395    Display - Branding
3      2018-01-10 0:21:09  151312395      Search - Special
4      2018-01-10 0:21:19  151312395    Display - Branding
5      2018-01-10 0:21:32  151312395    Display - Branding
6     2018-01-30 19:18:37  158490415               Display
7     2018-01-30 19:19:03  158490415               Display
8      2018-01-31 1:36:12  158490415              Branding

Моя цель - сопоставить порядок различных идентификаторов кампаний для каждого пользователя, чтобы проанализировать, какая кампания часто идет первой, второй, последней и т. д. Я удалил дубликаты, заказал метку времени, сгруппировал по идентификатору пользователя и поместил идентификатор кампании для каждого пользователя в массив. Теперь я хочу иметь цикл, который выполняет итерацию по каждому пользовательскому массиву, а затем назначает каждой кампании для каждого пользователя «место», например 1-е, 2-е, 3-е (шаг после этого будет заключаться в присвоении оценок каждой кампании в соответствии с тем, где в userjourney они есть, чтобы прояснить мою цель). Вот код, который у меня есть сейчас:

import pandas as pd
import numpy as np
import datetime
import os
import matplotlib.pyplot as plt


columnnames = ['date','user_id', 'ad_campaign']
df=pd.read_csv(r'C:\Users\L\Desktop\Data.csv' , 
    sep='\t',names = columnnames, usecols=[0,1,4],  
    parse_dates=True)

df=df.drop_duplicates(subset=['user_id','date', 'ad_campaign'])
df=df.set_index('date').sort_index()
df=(df.groupby(['user_id'])['ad_campaign'].apply(list)) 

print(df)

Теперь данные выглядят следующим образом:

user_id
151312395    [Search - Special, Display - Branding, Display...
158490415    [Display, Display, Branding, Display, Display,...
176204518    [Display, Display, Display, Display, Pathfinde...
182053572    [Branding, Branding, Branding, Display]

Я пробовал использовать цикл с iterrows, itertuples, itervalues ​​и т. д., Но я думаю, что мне что-то не хватает в том, как я храню эти данные, потому что я продолжаю получать разные ошибки. Какой цикл мне следует использовать?

Не могли бы вы вставить первые 5-10 строк C:\Users\L\Desktop\Attribution Data 4.csv в качестве текста в свой вопрос?

cs95 01.05.2018 15:51

Конечно, это нормально? (Фактические данные CSV имеют много столбцов, это то, что я читал)

Laila Van Ments 01.05.2018 15:55

Спасибо, очень полезно.

cs95 01.05.2018 16:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
3
46
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я сделаю тебе лучше. Давайте откажемся от промежуточного представления столбцов списков (с ним действительно сложно работать и он дает нулевой выигрыш в производительности). Вместо этого пометьте каждую кампанию своим уникальным порядковым номером (это делается с помощью groupby + cumcount), а затем вы можете сделать что-нибудь простое, например сгруппировать mean по кампаниям.

df = df.sort_values(by='date')

(df.groupby(['user_id'], sort=False)
   .cumcount()
   .groupby(df.ad_campaign)
   .mean()
   .sort_values(ascending=True)
)

ad_campaign
Display               0.5
Search - Special      0.5
Branding              2.0
Display - Branding    3.5
dtype: float64

Спасибо! Я пробовал использовать также min () и max () вместо mean (), который также работает. Но можете ли вы помочь мне понять, как интерпретировать эти три? Я просто пытаюсь понять, потому что мой следующий шаг - это более сложная модель, приписывающая 40% первой кампании в каждой пользовательской последовательности, 40% последней кампании в этой пользовательской последовательности и 20% деление между кампаниями в середине (попытка различных маркетинговых моделей атрибуции).

Laila Van Ments 01.05.2018 16:27

@LailaVanMents Я не уверен, что min или max имеют больше смысла в этом контексте, чем среднее, которое в основном усредняет позиции кампании во времени для каждого идентификатора пользователя. Основываясь на вашем объяснении, вы можете вместо этого рассмотреть возможность выполнения средневзвешенного значения, что может быть немного сложнее. Вы можете задать для этого новый вопрос, но это возможно.

cs95 01.05.2018 16:33

Другие вопросы по теме