2016-10-03 3 views
1

У меня есть следующие структуры данных:Как обрабатывать даты различию, используя тот же элементы идентификаторов в списке

[ (19L, datetime.datetime(2015, 2, 11, 12, 3, 43)), 
    (19L, datetime.datetime(2015, 2, 12, 16, 28, 48)), 
    (19L, datetime.datetime(2014, 9, 17, 11, 58, 19)), 
    (80L, datetime.datetime(2014, 9, 15, 12, 54, 36)), 
    (80L, datetime.datetime(2014, 9, 15, 14, 16, 39)), 
    (80L, datetime.datetime(2014, 2, 6, 8, 58, 39)), 
    (80L, datetime.datetime(2014, 9, 8, 14, 21, 48)), 
    (90L, datetime.datetime(2016, 8, 2, 18, 14, 31)), 
    (90L, datetime.datetime(2016, 8, 2, 21, 14, 23)), 
    (90L, datetime.datetime(2014, 1, 5, 16, 35, 34)) ] 

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

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

+0

В чем проблема? –

+0

Средняя частота посещения? – Aaron

+1

Вы можете [сортировать] (https://docs.python.org/2/library/functions.html#sorted), [группу] (https://docs.python.org/2/library/itertools.html# itertools.groupby) и средний. –

ответ

0

Вы можете использовать itertools.groupby() группе по идентификатору пользователя (при условии, список отсортирован по группируя ключ - который выглядит как это), то вы можете использовать «попарно» итерации и вычисляют среднее значение дня:

In [1]: import datetime 
In [2]: from operator import itemgetter 
In [3]: from itertools import groupby, combinations 

In [4]: l = [ 
    ...: (19L, datetime.datetime(2015, 2, 11, 12, 3, 43)), 
    ...: (19L, datetime.datetime(2015, 2, 12, 16, 28, 48)), 
    ...: (19L, datetime.datetime(2014, 9, 17, 11, 58, 19)), 
    ...: (80L, datetime.datetime(2014, 9, 15, 12, 54, 36)), 
    ...: (80L, datetime.datetime(2014, 9, 15, 14, 16, 39)), 
    ...: (80L, datetime.datetime(2014, 2, 6, 8, 58, 39)), 
    ...: (80L, datetime.datetime(2014, 9, 8, 14, 21, 48)), 
    ...: (90L, datetime.datetime(2016, 8, 2, 18, 14, 31)), 
    ...: (90L, datetime.datetime(2016, 8, 2, 21, 14, 23)), 
    ...: (90L, datetime.datetime(2014, 1, 5, 16, 35, 34)) ] 

In [5]: for user_id, dates in groupby(l, itemgetter(0)): 
    ...:  dates = [date[1] for date in dates] 
    ...:  differences = [abs((d1 - d2).days) for d1, d2 in zip(dates[0::2], dates[1::2])] 
    ...:  print(user_id, sum(differences)/len(differences)) 
    ...:  
(19L, 2) 
(80L, 108) 
(90L, 1) 
+0

Я бы подумал, что желаемый результат не будет средней разницей между всеми возможными комбинациями, а скорее средней разницей между последовательными временными отметками – Aaron

+0

Точно, моя ошибка, извините. Для первого пользователя среднее дневное расстояние должно быть 1 день. –

+0

@MarkF хорошо, обновил код в ответе - это то, что вы имели в виду? Благодарю. – alecxe

0

Я бы отсортировать метки времени в словарь, где каждый ключ Идентификатор пользователя и value - это список времени доступа. то после сортировки этого списка временных меток найдите разницу между каждым временем посещения и найдите среднее значение. объект datetime.timedelta может использоваться для упрощения математических операций на отметках времени.

from collections import defaultdict 
from datetime import datetime 

#l = [(id, datetime), (...), ...] 

d = defaultdict(list) 
for ID, time in l: 
    d[ID].append(time) # build list of times from timestamps 
    d[ID].sort() # sorting every time is not optimal but functional 

for ID in d.keys(): 
    timeDeltas = [d[ID][i+1] - d[ID][i] for i in range(len(d[ID])-1)] # create list of timedeltas 
    averageVisitFrequency = reduce(lambda x,y: x+y, timeDeltas)//len(timeDeltas) # calculate average timedelta 
    print 'user {} makes a purchase every {} days on average'.format(ID, averageVisitFrequency.days) # example output usage
+0

Отлично работает, и код его вполне понятен. Спасибо огромное ! –

 Смежные вопросы

  • Нет связанных вопросов^_^