Набор данных связан со временем, которое пользователь потратил на просмотр элементов:
user_id item_id view_started
121 160 2015-10-20 17:02:02
231 160 2015-10-18 11:02:29
231 161 2015-10-18 11:05:23
121 166 2015-10-18 11:04:34
231 180 2015-10-18 11:06:16
121 182 2015-10-20 17:02:10
134 182 2015-10-18 11:02:53
124 185 2015-10-18 11:04:23
231 187 2015-10-18 11:04:45
124 190 2015-10-18 11:05:43
Цель состоит в том, чтобы создать для каждого элемента время, потраченное пользователем на просмотр (или промежуток между просмотром элемента).
user_id item_id minutes
121 160 4320
...
Следует рассчитать разницу между непосредственным просмотром элемента. Пример: X1, X2, X3 | Time between X1-X2, X2-X3...
и для каждой группы необходимо сбросить время. Я считаю, что использование diff
- неправильный подход.
df.groupby(['user_id']).apply(
lambda x: x.sort_values(['view_started'], ascending = True))['view_started'].diff()
Это дает первое значение NaT
. Разница во времени должна быть сброшена для каждой группы (для каждого пользователя)
* Time probably don't reflect the above data frame due to sort
0 NaT
1 0 days 00:08:58
2 0 days 00:04:51
3 0 days 00:06:46
4 0 days 17:05:03
5 0 days 00:00:51
6 -9 days +10:21:49
7 0 days 00:02:33
diff
здесь кажется прекрасным, но вам нужно будет немного поработать. Сначала отсортируйте данные:
df = df.sort_values(by=['user_id', 'view_started']).reset_index(drop=True)
Теперь вы можете выполнить операцию groupby
+ diff
.
df['minutes'] = (
df.groupby('user_id', sort=False)
.view_started
.diff()
.dt.total_seconds()
.div(60)
.shift(-1)
)
df
user_id item_id view_started minutes
0 121 166 2015-10-18 11:04:34 3237.466667
1 121 160 2015-10-20 17:02:02 0.133333
2 121 182 2015-10-20 17:02:10 NaN
3 124 185 2015-10-18 11:04:23 1.333333
4 124 190 2015-10-18 11:05:43 NaN
5 134 182 2015-10-18 11:02:53 NaN
6 231 160 2015-10-18 11:02:29 2.266667
7 231 187 2015-10-18 11:04:45 0.633333
8 231 161 2015-10-18 11:05:23 0.883333
9 231 180 2015-10-18 11:06:16 NaN
@ Null-Hypothesis. Наблюдаемые минуты должны быть связаны с записью чуть выше того места, где она фактически создается, поэтому я сдвигаю ее вверх. Например, X -> Y изначально будет генерировать NaN, xyz mins, даже если xyz связан с элементом X, а не Y. Что касается NaN, вы можете рассмотреть возможность заполнения средним значением, что-то вроде df.minutes = df.minutes.fillna(df.groupby('user_id').minutes.transform('mean'))
. Вы также можете использовать импьютер sklearn, но он не может обрабатывать групповые операции заполнения.
@COLDSPEED, что здесь за работа
shift(-1)
? какие-либо рекомендации для NaN, замените на Среднее на пользователя ?.