2014-09-09 32 views
7

Ho una lista in cui ogni valore è un elenco di tuple. per esempio questo è il valore che estraggo per una chiave:come aggregare elementi di un elenco di tuple se le tuple hanno lo stesso primo elemento?

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

Ho anche ordinato la lista. ora voglio aggregare i valori in questo modo:

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

in un certo senso voglio gruppo miei tuple in termini di mesi, per riassumere le interi per ogni mese assieme, ho letto su groupby e penso che non posso aiutarmi con la mia struttura dati perché non ho idea di cosa troverò di fronte nella mia lista, quindi sto cercando di trovare un modo per dire: inizia dai primi elementi delle tuple if io [0] [: 6] sono uguali: somma i [1]. ma sto affrontando difficoltà per implementare questa idea.

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

Apprezzerei qualsiasi consiglio dato che sono un nuovo utente di Python!

risposta

1

Ancora un'altra risposta diversa da quelle già fornite. Puoi semplificare la creazione di un nuovo dizionario in cui le chiavi sono le combinazioni anno-mese. Un loop sulle date nella tua lista + usando dictionary.get(key, defaultvalue) dovrebbe fare il trucco. IT aggiunge il valore corrente al valore nel nuovo dizionario, se la chiave non esiste ancora, restituisce il valore predefinito 0 e crea la chiave.

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

Provare a utilizzare itertools.groupby ai valori aggregati per mese:

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 

Ecco una versione one-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

grazie. È una buona soluzione, ma quando la eseguo nel mio set di dati ho risultati come: 2000-05 17 2000-05 17 2000-07 5 Sto cercando di capire perché il 2000-05 viene ripetuto due volte. – Singu

+0

@Singu non capisco cosa dicono i tuoi dati hanno duplicati –

+0

no i miei dati non hanno duplicati, lo eseguo e ottengo i risultati giusti ma non ho idea del perché per ogni query la prima riga dei risultati viene stampata due volte ! ancora qualche minuto e darò il feedback. Grazie! – Singu

0

Mi piace usare defaultdict per il conteggio:

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

Proprio utilizzare 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

grazie! ma stampa l'oggetto della data! – Singu

+0

Non sono sicuro di cosa intendi. Puoi pubblicare l'output effettivo. –

+0

questa è una riga dall'output: defaultdict (, {'2000-05': 17, '2000-07': 5}) – Singu

Problemi correlati