Панды вычисляют разницу в дате и времени, но для каждого пользователя

Набор данных связан со временем, которое пользователь потратил на просмотр элементов:

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
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
45
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

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

@COLDSPEED, что здесь за работа shift(-1)? какие-либо рекомендации для NaN, замените на Среднее на пользователя ?.

add-semi-colons 30.04.2018 22:10

@ Null-Hypothesis. Наблюдаемые минуты должны быть связаны с записью чуть выше того места, где она фактически создается, поэтому я сдвигаю ее вверх. Например, X -> Y изначально будет генерировать NaN, xyz mins, даже если xyz связан с элементом X, а не Y. Что касается NaN, вы можете рассмотреть возможность заполнения средним значением, что-то вроде df.minutes = df.minutes.fillna(df.groupby('user_id').minutes.transform('m‌​ean')). Вы также можете использовать импьютер sklearn, но он не может обрабатывать групповые операции заполнения.

cs95 30.04.2018 22:16

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