Анализировать список питонов с помощью алгоритма подсчета событий по диапазонам дат - PullRequest
2 голосов
/ 11 января 2009

Ниже показана структура некоторых данных, которые у меня есть (формат: список списков)

data = 
[ 
  [1,2008-12-01],
  [1,2008-12-01],
  [2,2008-12-01]
  ... (the lists continue)
]

Даты варьируются с 2008-12-01 по 2008-12-25.

Первое поле идентифицирует пользователя по идентификатору, второе поле (поле даты) показывает, когда этот пользователь посетил страницу на моем сайте.

Мне нужно проанализировать эти данные, чтобы получить следующие результаты

25 пользователей посетили 1 день
100 пользователей посетило сайт за 2 дня
300 пользователей посетили за 4 дня
... до 25 дней

Я использую python и не знаю с чего начать!

EDIT

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

Мне нужно узнать, сколько пользователей посетили все дни, например,
10 пользователей посетили за 25 дней (или каждый день)

Тогда я бы хотел перечислить то же самое для каждой частоты дней от 1 до 25. Так же, как в моем исходном примере выше
25 пользователей посетили только за один день (из 25)
100 пользователей посетили за 2 дня (из 25)
и т. д.

Мне НЕ нужно знать, сколько посетило каждый день
спасибо

Ответы [ 6 ]

4 голосов
/ 11 января 2009

Ваш результат - словарь, верно?

{ userNumber: setOfDays }

Как насчет этого, чтобы начать.

from collections import defaultdict
visits = defaultdict(set)
for user, date in someList:
    visits[user].add(date)

Это дает вам словарь с набором дат, в которые они побывали.

counts = defaultdict(int)
for user in visits:
    v= len(visits[user])
    count[v] += 1

Это дает вам словарь # посещений, # пользователей с таким количеством посещений.

Это то, что вы ищете?

1 голос
/ 12 января 2009

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

>>> log=[[1, '2008-12-01'], [1, '2008-12-01'],[2, '2008-12-01'],[2, '2008-12-03'], [1, '2008-12-04'], [3, '2008-12-04'], [4, '2008-12-04']]
>>> all_dates = sorted(set([d for d in [x[1] for x in log]]))
>>> for i in range(0, len(all_dates)):
...     log_slice = [d for d in log if d[1] <= all_dates[i]]
...     num_users = len(set([u for u in [x[0] for x in log_slice]]))
...     print "%d users visited in %d days" % (num_users, i + 1)
... 
2 users visited in 1 days
2 users visited in 2 days
4 users visited in 3 days
>>> 
1 голос
/ 12 января 2009

Переписать ответ С. Лотта на SQL в качестве упражнения, просто чтобы убедиться, что я правильно выполнил требования ...

SELECT * FROM someList;

 userid |    date    
--------+------------
      1 | 2008-12-01
      1 | 2008-12-02
      1 | 2008-12-03
      1 | 2008-12-04
      1 | 2008-12-05
      2 | 2008-12-03
      2 | 2008-12-04
      2 | 2008-12-05
      3 | 2008-12-04
      4 | 2008-12-04
      5 | 2008-12-05
      5 | 2008-12-05

SELECT countdates, COUNT(userid) AS nusers
FROM ( SELECT userid, COUNT (DISTINCT date) AS countdates
             FROM someList
             GROUP BY userid ) AS visits
GROUP BY countdates
HAVING countdates <= 25
ORDER BY countdates;

 countdates | nusers 
------------+--------
          1 |      3
          3 |      1
          5 |      1
0 голосов
/ 12 января 2009

Как насчет этого: это дает вам набор дней, а также счет:

In [39]: from itertools import groupby ##itertools is a part of the standard library.

In [40]: l=[[1, '2008-12-01'],
   ....:  [1, '2008-12-01'],
   ....:  [2, '2008-12-01'],
   ....:  [1, '2008-12-01'],
   ....:  [3, '3008-12-04']]

In [41]: l.sort()

In [42]: l
Out[42]: 
[[1, '2008-12-01'],
 [1, '2008-12-01'],
 [1, '2008-12-01'],
 [2, '2008-12-01'],
 [3, '3008-12-04']]

In [43]: for key, group in groupby(l, lambda x: x[0]):
   ....:     group=list(group)
   ....:     print key,' :: ', len(group), ' :: ', group
   ....:     
   ....:     
1  ::  3  ::  [[1, '2008-12-01'], [1, '2008-12-01'], [1, '2008-12-01']]
2  ::  1  ::  [[2, '2008-12-01']]
3  ::  1  ::  [[3, '3008-12-04']]

пользователь :: количество посещений :: даты посещения

Здесь пользователь -1 посещает 2008-12-01 3 раза, если вы хотите считать только разные даты, тогда

for key, group in groupby(l, lambda x: x[0]):
    group=list(group)
    print key,' :: ', len(set([(lambda y: y[1])(each) for each  in group])), ' :: ', group
   ....:     
   ....:     
1  ::  1  ::  [[1, '2008-12-01'], [1, '2008-12-01'], [1, '2008-12-01']]
2  ::  1  ::  [[2, '2008-12-01']]
3  ::  1  ::  [[3, '3008-12-04']]
0 голосов
/ 12 января 2009

Неясно, каковы именно ваши требования. Вот мой дубль:

#!/usr/bin/env python
from collections import defaultdict

data = [ 
  [1,'2008-12-01'],
  [3,'2008-12-25'],
  [1,'2008-12-01'],
  [2,'2008-12-01'],
]

d = defaultdict(set)
for id, day in data:
    d[day].add(id)

for day in sorted(d):
    print('%d user(s) visited on %s' % (len(d[day]), day))

Он печатает:

2 user(s) visited on 2008-12-01
1 user(s) visited on 2008-12-25
0 голосов
/ 12 января 2009

Во-первых, я должен упомянуть, что вам НУЖНО хранить дату в виде строки. В настоящее время он будет делать арифметику для вашей текущей записи. Итак, если вы отформатируете data, как это, он будет работать лучше:

data = 
[ 
  [1,"2008-12-01"],
  [1,"2008-12-01"],
  [2,"2008-12-01"]
]

Далее, мы можем сделать что-то вроде этого, чтобы получить номер для каждого дня:

result = {}
for (id, date) in data:
    if date not in result:
        result[date] = 1
    else:
        result[date] += 1

Теперь вы можете узнать количество пользователей на определенную дату, выполнив что-то вроде этого:

print result[some_date]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...