2017-06-28 4 views
0

ich eine Liste mit zwei Integer-Felder haben, die Ich mag würde (string, integer, integer) zusammenzufassenPython-Liste Gruppe und die Summe mit mehreren Feldern

myList= [[["26-07-2017",2,0], ["26-07-2017",3,0], ["27-07-2017",1,0], ["27-07-2017",0,1]]] 

Nun möchte Ich mag nach dem Datum zu gruppieren und zusammenzufassen die int-Felder So sollte die Ausgabe so sein:

sumList= [[["26-07-2017",5,0], ["27-07-2017",1,1]]] 

Wie kann ich das erreichen? Danke für die Antwort.

+0

Was haben Sie bisher versuchen? – Antwane

+0

Sind gleiche Felder garantiert nebeneinander? – anonymoose

+1

Sieht aus wie ein Lehrbuchbeispiel für defaultdict. –

Antwort

3

Sie können Verwenden Sie itertools.groupby bis Gruppe die Elemente am Datum, dann verwenden Sie reduce zusammenzufassen Zahlen in jeder Gruppe:

from itertools import groupby 

lst = [[k] + reduce(lambda x, y: [y[1]+x[1], y[2]+x[2]], g) 
          for k, g in groupby(myList[0], lambda x: x[0])] 
print [lst] 
# [[['26-07-2017', 5, 0], ['27-07-2017', 1, 1]]] 

Python 3 erfordert reduce importieren: from functools import reduce


Sie konnten die relativ weniger intuitve reduce, indem die (auch in Unterwerfung unter GvR) vermeiden, mit Summen in einer for-Schleife:

from itertools import groupby 

lst = [] 
for k, g in groupby(myList[0], lambda x: x[0]): 
    g = [sum(d) for d in zip(*(t[1:] for t in g))] 
    lst.append([k] + g) 
print [lst] 
# [[['26-07-2017', 5, 0], ['27-07-2017', 1, 1]]] 
+1

In Python 3.X, reduce ist nicht mehr eingebaut, es wurde in functools verschoben, falls die Leute es brauchen. – Tbaki

2

Sie können sich wahrscheinlich dies mit Pandas

import pandas as pd 

df = pd.DataFrame(myList[0]) 
answer = df.groupby([0]).sum() 

gibt mir

  1 2 
0    
26-07-2017 5 0 
27-07-2017 1 1 

EDIT: ich Ihre Liste verwendet, wie oben, aber mit einigen Änderungen, die Code macht ein bisschen mehr Sinn:

# name the columns 
df = pd.DataFrame(myList[0], columns=['date', 'int1', 'int2']) 

# group on the date column 
df.groupby(['date']).sum() 

kehrt

  int1 int2 
date     
26-07-2017  5  0 
27-07-2017  1  1 

und die Datenrahmen wie folgt aussieht:

  date int1 int2 
0 26-07-2017  2  0 
1 26-07-2017  3  0 
2 27-07-2017  1  0 
3 27-07-2017  0  1 
+0

Dies kann auf andere Weise getan werden, aber wenn Sie 'Pandas' verwenden können, ist es eine wirklich nette Bibliothek – NightHallow

0

ich ein Wörterbuch verwenden würde Spur wie ersten Einträge zu halten, wie es so:

my_dict = {} 
for entry in myList: 
    if entry[0] not in my_dict: 
     #This makes my_dict hold dates as keys and a list of 2 integers as values 
     my_dict[entry[0]] = [entry[1:]] 
    else: 
     #In the case that the date is already in my_dict, add the new integers 
     my_dict[entry[0]][0] += entry[1] 
     my_dict[entry[0]][1] += entry[2] 
#Now my_dict holds dates as keys with all the sums following 
#If I really need it to be in the list format you asked for: 
sumList = [] 
for value in my_dict: 
    sumList.append(value, my_dict[value][0], my_dict[value][1]) 
0

Sie können dict verwenden, um Ihre un zu speichern ique Daten und die Summe der Werte

Code:

myList= [[["26-07-2017",2,0], ["26-07-2017",3,0], ["27-07-2017",1,0], ["27-07-2017",0,1]]] 
dic = {} 
for x in myList[0]: 
    try: 
     dic[x[0]][0] = dic[x[0]][0]+x[1] 
     dic[x[0]][1] = dic[x[0]][1] + x[2] 
    except: 
     dic[x[0]] = [x[1], x[2]] 
[[k,v[0], v[1]]for k,v in dic.items()] 

Ausgang:

[['26-07-2017', 5, 0], ['27-07-2017', 1, 1]]