2014-09-09 8 views
7

Mam listę, w której każda wartość jest listą krotek. na przykład jest to wartość, którą wydobywam dla klucza:jak agregować elementy listy krotek, jeśli krotki mają ten sam pierwszy element?

 [('1998-01-20',8) , ('1998-01-22',4) , ('1998-06-18',8) , ('1999-07-15' , 7), ('1999-07-21',1) ] 

Posortowałem również listę. teraz chcę agregowanie wartości tak:

[('1998-01' , 12) , ('1998-06' ,8) , ('1999-07',8)] 

w pewnym sensie chcę grupy moich krotki pod względem miesiąca, podsumowując INTów dla każdego miesiąca razem, czytałem o GroupBy i myślę, że nie może mi pomóc z moją strukturą danych, ponieważ nie mam pojęcia, co mam napotkać na mojej liście, więc staram się znaleźć sposób, aby powiedzieć: zacznij od pierwszych elementów krotek, jeśli ja [0] [: 6] są równe: sum i [1]. ale mam trudności z wdrożeniem tego pomysłu.

for i in List : 
     if i[0][:6] # *problem* I don't know how to say my condition : 
     s=sum(i[1]) #? 

Byłbym wdzięczny za wszelkie porady, ponieważ jestem nowym użytkownikiem Pythona!

Odpowiedz

1

Jeszcze inna odpowiedź, inna od podanych. Możesz utworzyć nowy słownik, w którym klucze są kombinacjami rok-miesiąc. Pętla ponad datami na liście + przy użyciu dictionary.get(key, defaultvalue) powinna wystarczyć. IT dodaje bieżącą wartość do wartości w nowym słowniku, jeśli klucz jeszcze nie istniał, zwraca wartość domyślną 0 i tworzy klucz.

data = [('1998-01-20',8) , ('1998-01-22',4) , ('1998-06-18',8) , ('1999-07-15' , 7), ('1999-07-21',1)] 
dictionary = dict() 
for (mydate, val) in data: # 
    ym = mydate[0:7] # the key is only the year month combination (i.e. '1998-01' for example) 
    dictionary[ym] = dictionary.get(ym, 0) + val # return the value for that key or return default 0 (and create key) 

data_aggregated = [(key, val) for (key, val) in dictionary.iteritems()] # if you need it back in old format 
10

Spróbuj użyć itertools.groupby do wartości zagregowanych przez miesiąc:

from itertools import groupby 
a = [('1998-01-20', 8), ('1998-01-22', 4), ('1998-06-18', 8), 
    ('1999-07-15', 7), ('1999-07-21', 1)] 

for key, group in groupby(a, key=lambda x: x[0][:7]): 
    print key, sum(j for i, j in group) 

# Output 

1998-01 12 
1998-06 8 
1999-07 8 

Oto wersja jedno-liner:

print [(key, sum(j for i, j in group)) for key, group in groupby(a, key=lambda x: x[0][:7])] 

# Output 

[('1998-01', 12), ('1998-06', 8), ('1999-07', 8)] 
+0

dziękuję. To dobre rozwiązanie, ale gdy uruchomię go w zbiorze danych, mam wyniki takie jak: 2000-05 17 2000-05 17 2000-07 5 Próbuję zrozumieć, dlaczego 2000-05 jest powtarzany dwa razy. – Singu

+0

@Sing i dint dostaję to, co mówisz, twoje dane mają duplikaty –

+0

żadne moje dane nie mają duplikatów, uruchamiam je i uzyskuję właściwe wyniki, ale nie mam pojęcia, dlaczego dla każdego zapytania pierwsza linia wyników jest drukowana dwa razy ! kilka minut, a ja dam znać. dzięki! – Singu

0

Lubię używać defaultdict do liczenia:

from collections import defaultdict 

lst = [('1998-01-20',8) , ('1998-01-22',4) , ('1998-06-18',8) , ('1999-07-15' , 7), ('1999-07-21',1)] 

result = defaultdict(int) 

for date, cnt in lst: 
    year, month, day = date.split('-') 
    result['-'.join([year, month])] += cnt 

print(result) 
3

Wystarczy użyj defaultdict:

from collections import defaultdict 


DATA = [ 
    ('1998-01-20', 8), 
    ('1998-01-22', 4), 
    ('1998-06-18', 8), 
    ('1999-07-15', 7), 
    ('1999-07-21', 1), 
] 


groups = defaultdict(int) 
for date, value in DATA: 
    groups[date[:7]] += value 


from pprint import pprint 
pprint(groups) 
+1

dziękuję! ale drukuje "obiekt" daty! – Singu

+0

Nie jestem pewien, co masz na myśli. Czy możesz opublikować rzeczywiste wyniki? –

+0

jest to wiersz z wyjścia: defaultdict (, {'2000-05': 17, '2000-07': 5}) – Singu

Powiązane problemy