У меня есть таблица, в которой хранятся данные о транзакциях клиентов. Дата покупки всегда указывается в начале месяца. Если покупатель совершал покупки более одного раза в течение месяца, оба счета на покупку выставляются в один и тот же день.
Дата | Пользовательский ИД |
---|---|
01.02.20 | 1 |
01.03.20 | 1 |
01.03.20 | 1 |
01.03.20 | 1 |
Для моих дальнейших расчетов я хотел бы теперь удалить «дубликаты», увеличив дату на один день для повторных покупок в месяц. Как я могу сделать это, чтобы получить желаемый результат с помощью python?
Дата | Пользовательский ИД |
---|---|
01.02.20 | 1 |
01.03.20 | 1 |
02.03.20 | 1 |
03.03.20 | 1 |
Как описано выше, у меня есть дубликаты, когда я смотрю только на CustomerID и дату покупки. Я хотел бы решить эту проблему, изменив дату. День следует увеличивать на единицу до тех пор, пока не останется дубликатов. Я думал о возможном использовании цикла while. Но я не уверен, что это может работать таким образом.
Один из способов сделать это — сгруппировать по датам, а затем преобразовать их в диапазон дат на основе количества вхождений определенного идентификатора клиента.
Во-первых, мы хотели бы, чтобы даты представлялись пандами внутри как фактические даты, а не строки.
df["Date"] = pd.to_datetime(df["Date"], format = "%d.%m.%y")
Далее мы группируем данные по идентификатору клиента и датам. В вашем случае есть только 2020 год, поэтому группировка только по месяцам — это нормально, но мы хотели бы быть готовыми к будущему, поэтому мы также будем группировать по годам. dt
относится к «дате и времени» и извлекает для нас соответствующую информацию.
gb = df.groupby(["CustomerID", df.Date.dt.year, df.Date.dt.month])
Затем мы можем использовать немного магии панд. Для каждой группы мы получаем первую дату, которая всегда будет первым днем данного месяца. Мы создаем диапазон дней, начиная с этого дня, который пропорционален количеству наблюдений в этой группе и вуаля.
idx = gb["Date"].transform(lambda x : pd.date_range(x.iloc[0],
periods=x.count(),
freq = "D"))
idx
выглядит так:
0 2020-02-01
1 2020-03-01
2 2020-03-02
3 2020-03-03
Name: Date, dtype: datetime64[ns]
Наконец, мы знаем, что во вновь созданном idx
содержится столько же значений, сколько и в исходном фрейме данных, а это означает, что мы можем использовать эту переменную как индекс и или как новый столбец.
(Выберите один из двух в зависимости от ваших потребностей)
df.index = idx # as index
df["Date_fixed"] = idx # as column
N.B. Это решение может вызвать проблемы, если в данном месяце имеется больше идентификаторов клиентов, чем дней в месяце. Так что с этим надо быть осторожнее =)
@lemonbub Отлично! Затем отметьте это как исправленное для дальнейшего использования (нажмите на зеленую галочку, чтобы подтвердить ответ).
Пожалуйста, уточните вашу конкретную проблему или предоставьте дополнительную информацию, чтобы выделить именно то, что вам нужно. Как сейчас написано, трудно точно сказать, о чем вы спрашиваете.