2014-12-19 2 views
2

У меня есть набор данных, в котором каждая запись содержит дату, когда пользователь чирикал, их имя экрана, подсчет их последователей и их друг. Пользователи могут быть перечислены несколько раз на протяжении всего набора данных и в разное время, а также с разными подсчетами следящих/друзей в эти различные моменты времени. То, что я хотел бы сделать, - это получить уникальный список пользователей в списке и их последних счетчиков/друзей. Я не хочу просто дублировать их имя, но вместо этого хочу получить самые последние значения.Python - Как дедуплицировать список кортежей, сохраняя только самые последние кортежи.

Это то, что мои данные в настоящее время выглядит как с повторяющимися значениями

In [14]: data 
Out[14]: 
[(datetime.datetime(2014, 11, 21, 1, 16, 2), u'AlexMatosE', 773, 560), 
(datetime.datetime(2014, 11, 21, 1, 17, 6), u'hedofthebloom', 670, 618), 
(datetime.datetime(2014, 11, 21, 1, 18, 8), u'hedofthebloom', 681, 615), 
(datetime.datetime(2014, 11, 21, 1, 19, 1), u'jape2116', 263, 540), 
(datetime.datetime(2014, 11, 21, 1, 19, 3), u'_AlexMatosE', 790, 561), 
(datetime.datetime(2014, 11, 21, 1, 19, 5), u'Buffmuff69', 292, 270), 
(datetime.datetime(2014, 11, 21, 1, 20, 1), u'steveamodu', 140, 369), 
(datetime.datetime(2014, 11, 21, 1, 20, 9), u'jape2116', 263, 540), 
(datetime.datetime(2014, 11, 21, 1, 21, 3), u'chighway', 363, 767), 
(datetime.datetime(2014, 11, 21, 1, 22, 9), u'jape2116', 299, 2000)] 

Это, как я могу получить уникальные пользователь в данных

In [15]: users = set(sorted([line[1] for line in data])) 

Теперь мне нужно выяснить, как получить набор значений MOST RECENT для каждого уникального пользователя в наборе данных. Я не уверен, что для цикла это лучший способ пойти сюда, или если что-то еще будет лучше.

In [18]: most_recent_user_data = [] 
    ....: for line in data: 
    ....:  if line[1] in users: 
    ....:   ... 
    ....:   ... 
    ....:   ... 
    ....:   most_recent_user_data.append((line[1], line[2], line[3])) 

Окончательные, я хочу, чтобы в конечный итоге с каждым уникальным пользователем один раз, и их ПОСЛЕДНИЕ последователи/друзья ценят

In [19]: most_recent_user_data 
Out[19]: 
(u'hedofthebloom', 681, 615), 
(u'_AlexMatosE', 790, 561), 
(u'Buffmuff69', 292, 270), 
(u'steveamodu', 140, 369), 
(u'chighway', 363, 767), 
(u'jape2116', 299, 2000)] 
+0

Вы пробовали группировку по пользователю, сортируя по tim estamp, и получить самую последнюю? – chapelo

ответ

0

Один из способов будут использовать словари и использовать имена пользователей в качестве ключей , Для каждого ключа у вас будет список пользовательских данных, которые вы можете отсортировать по своему усмотрению. Ниже приведен один из способов сделать это:

from collections import defaultdict 

# move data to a dict 
dataDict = defaultdict(list) 

for v in data: 
    dataDict[v[1]] += [v] 

# sort user data for each user/key 
for u,v in dataDict.items(): 
    dataDict[u] = sorted(v, reverse=True) 

# get first (i.e. most recent) values for each user  
for u,v in dataDict.items(): 
    print(u,v[0][-2], v[0][-1])  

Результат:

(u'chighway', 363, 767) 
(u'AlexMatosE', 773, 560) 
(u'hedofthebloom', 681, 615) 
(u'steveamodu', 140, 369) 
(u'Buffmuff69', 292, 270) 
(u'_AlexMatosE', 790, 561) 
(u'jape2116', 299, 2000) 
0

Использование словаря для сохранения последних данных для каждого пользователя.

latests = {} 
for d in data: 
    if d[0] > latests.setdefault(d[1], d)[0]: 
     latests[d[1]] = d 

results = [(d[1], d[2:]) for d in latests.values()] 
from pprint import pprint 
pprint(results) 
0

Альтернативный способ, чтобы получить желаемый результат:

from operator import itemgetter 

# sort the data using time as the key 
data.sort(key=itemgetter(0), reverse=True) 

# remove duplicated users from the data 
def uniq(seq): 
    seen = set() 
    seen_add = seen.add 
    return [(x[1], x[2], x[3]) for x in seq if not (x[1] in seen or seen_add(x[1]))] 

uniq(data) 

, который дает:

[('jape2116', 299, 2000), 
('chighway', 363, 767), 
('steveamodu', 140, 369), 
('Buffmuff69', 292, 270), 
('_AlexMatosE', 790, 561), 
('hedofthebloom', 681, 615), 
('AlexMatosE', 773, 560)] 

Я использую метод, упомянутый в this thread.

1

Вы можете использовать groupby функцию в itertools модуле:

import datetime 
import itertools 

data = [(datetime.datetime(2014, 11, 21, 1, 16, 2), u'AlexMatosE', 773, 560), 
     (datetime.datetime(2014, 11, 21, 1, 17, 6), u'hedofthebloom', 670, 618), 
     (datetime.datetime(2014, 11, 21, 1, 18, 8), u'hedofthebloom', 681, 615), 
     (datetime.datetime(2014, 11, 21, 1, 19, 1), u'jape2116', 263, 540), 
     (datetime.datetime(2014, 11, 21, 1, 19, 3), u'_AlexMatosE', 790, 561), 
     (datetime.datetime(2014, 11, 21, 1, 19, 5), u'Buffmuff69', 292, 270), 
     (datetime.datetime(2014, 11, 21, 1, 20, 1), u'steveamodu', 140, 369), 
     (datetime.datetime(2014, 11, 21, 1, 20, 9), u'jape2116', 263, 540), 
     (datetime.datetime(2014, 11, 21, 1, 21, 3), u'chighway', 363, 767), 
     (datetime.datetime(2014, 11, 21, 1, 22, 9), u'jape2116', 299, 2000)] 

# sorted record by name and datetime 
data = sorted(data, key=lambda x: (x[1], x[0]), reverse=True) 

# group by username and get the most recent user data 
most_recent_user_data = [[(lambda x: (x[1], x[2], x[3]))(next(v)) for k, v in itertools.groupby(data, key=lambda x: x[1])]] 

результат:

[('steveamodu', 140, 369), 
('jape2116', 299, 2000), 
('hedofthebloom', 681, 615), 
('chighway', 363, 767), 
('_AlexMatosE', 790, 561), 
('Buffmuff69', 292, 270), 
('AlexMatosE', 773, 560)] 
0

Вы упорядочивать набор данных в обратном порядке времени и добавить в словарь или добавить в список только первый время, когда пользователь показывает:

import datetime  
users = {} 
for d in reversed(data): 
    if d[1] not in users: users[d[1]] = tuple(d[2:]) 

# {'_AlexMatosE': (790, 561), 'steveamodu': (140, 369), 'jape2116': (299, 2000), 'chighway': (363, 767), 'AlexMatosE': (773, 560), 'hedofthebloom': (681, 615), 'Buffmuff69': (292, 270)} 
Смежные вопросы