среднее время активности

#python #python-3.x #python-datetime

#python #python-3.x #python-дата и время

Вопрос:

У меня есть массив json, где у меня будут id, starttime, endtime. Я хочу рассчитать среднее время активности пользователя. И у некоторых может быть только время начала, но не время окончания. Пример данных —

 data = [{"id":1, "stime":"2020-09-21T06:25:36Z","etime": "2020-09-22T09:25:36Z"},{"id":2, "stime":"2020-09-22T02:24:36Z","etime": "2020-09-23T07:25:36Z"},{"id":3, "stime":"2020-09-20T06:25:36Z","etime": "2020-09-24T09:25:36Z"},{"id":4, "stime":"2020-09-23T06:25:36Z","etime": "2020-09-29T09:25:36Z"}]
  

Мой метод для достижения этой цели — разница между startine и endtime. затем суммируйте все время разницы и разделите на количество общего числа идентификаторов.

пример кода:

 import datetime
from datetime import timedelta
import dateutil.parser

datetimeFormat = '%Y-%m-%d %H:%M:%S.%f'
date_s_time = '2020-09-21T06:25:36Z'
date_e_time = '2020-09-22T09:25:36Z'
d1 = dateutil.parser.parse(date_s_time)
d2 = dateutil.parser.parse(date_e_time)
diff1 = datetime.datetime.strptime(d2.strftime('%Y-%m-%d %H:%M:%S.%f'), datetimeFormat)
    - datetime.datetime.strptime(d1.strftime('%Y-%m-%d %H:%M:%S.%f'), datetimeFormat)
    
print("Difference 1:", diff1)

date_s_time2 = '2020-09-20T06:25:36Z'
date_e_time2 = '2020-09-28T02:25:36Z'
d3 = dateutil.parser.parse(date_s_time2)
d4 = dateutil.parser.parse(date_e_time2)
diff2 = datetime.datetime.strptime(d4.strftime('%Y-%m-%d %H:%M:%S.%f'), datetimeFormat)
    - datetime.datetime.strptime(d3.strftime('%Y-%m-%d %H:%M:%S.%f'), datetimeFormat)
 
print("Difference 2:", diff2)

print("total", diff1 diff2)

print(diff1 diff2/2)
  

пожалуйста, подскажите мне, есть ли лучший подход, который будет эффективным.

Ответ №1:

Вы могли бы использовать pandas библиотеку.

 import pandas as pd

data = [{"id":1, "stime":"2020-09-21T06:25:36Z","etime": "2020-09-22T09:25:36Z"},{"id":1, "stime":"2020-09-22T02:24:36Z","etime": "2020-09-23T07:25:36Z"},{"id":1, "stime":"2020-09-20T06:25:36Z","etime": "2020-09-24T09:25:36Z"},{"id":1, "stime":"2020-09-23T06:25:36Z"}]
  

(Допустим, у вашей последней строки нет времени окончания)

Теперь вы можете создать фрейм данных Pandas, используя свои данные

 df = pd.DataFrame(data)
  

df выглядит так:

    id                 stime                 etime
0   1  2020-09-21T06:25:36Z  2020-09-22T09:25:36Z
1   1  2020-09-22T02:24:36Z  2020-09-23T07:25:36Z
2   1  2020-09-20T06:25:36Z  2020-09-24T09:25:36Z
3   1  2020-09-23T06:25:36Z                   NaN
  

Теперь мы хотим сопоставить столбцы stime и etime , чтобы строки были преобразованы в объекты datetime, и заполнить NaN s чем-то, что имеет смысл: если время окончания не существует, можем ли мы использовать текущее время?

 df = df.fillna(datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ'))
df['etime'] = df['etime'].map(dateutil.parser.parse)
df['stime'] = df['stime'].map(dateutil.parser.parse)
  

Или, если вы хотите удалить строки, в которых нет etime , просто сделайте

 df = df.dropna()
  

Теперь df становится:

    id                     stime                     etime
0   1 2020-09-21 06:25:36 00:00 2020-09-22 09:25:36 00:00
1   1 2020-09-22 02:24:36 00:00 2020-09-23 07:25:36 00:00
2   1 2020-09-20 06:25:36 00:00 2020-09-24 09:25:36 00:00
3   1 2020-09-23 06:25:36 00:00 2020-09-24 20:05:42 00:00
  

Наконец, вычтите два:

 df['tdiff'] = df['etime'] - df['stime']
  

и мы получаем:

    id                     stime                     etime           tdiff
0   1 2020-09-21 06:25:36 00:00 2020-09-22 09:25:36 00:00 1 days 03:00:00
1   1 2020-09-22 02:24:36 00:00 2020-09-23 07:25:36 00:00 1 days 05:01:00
2   1 2020-09-20 06:25:36 00:00 2020-09-24 09:25:36 00:00 4 days 03:00:00
3   1 2020-09-23 06:25:36 00:00 2020-09-24 20:05:42 00:00 1 days 13:40:06
  

Среднее значение этого столбца равно:

 df['tdiff'].mean()
Output: Timedelta('2 days 00:10:16.500000')
  

Комментарии:

1. Спасибо, что, если у какого-либо идентификатора нет времени окончания? Не имеет значения etime и stime 2020-09-22T09:25:36Z

2. я не хочу вычислять, равно ли etime None.. как я могу этого добиться

3. Спасибо, пранав