2016-08-09 3 views
3

ich eine Liste der Wörterbücher der folgende Form haben:Python Summenwerte der Liste der Wörterbücher, wenn zwei anderen Schlüsselwertepaare entsprechen

lst = [{"Name":'Nick','Hour':0,'Value':2.75}, 
     {"Name":'Sam','Hour':1,'Value':7.0}, 
     {"Name":'Nick','Hour':0,'Value':2.21}, 
     {'Name':'Val',"Hour":1,'Value':10.1}, 
     {'Name':'Nick','Hour':1,'Value':2.1}, 
     {'Name':'Val',"Hour":1,'Value':11},] 

Ich möchte für eine bestimmte alle Werte für einen Namen summieren können, Stunde, z Wenn Name == Nick and Hour == 0, möchte ich Wert geben Sie mir die Summe aller Werte, die die Bedingung erfüllen. 2.75 + 2.21, nach dem obigen Stück.

Ich habe bereits folgendes versucht, aber es hilft mir nicht mit beiden Bedingungen.

finalList = collections.defaultdict(float) 
for info in lst: 
    finalList[info['Name']] += info['Value'] 
finalList = [{'Name': c, 'Value': finalList[c]} for c in finalList] 

Dieser fasst alle Werte für ein bestimmtes Name auf, die Überprüfung nicht, wenn die Hour das gleiche ist. Wie kann ich diese Bedingung in meinen Code integrieren?

Meine erwartete Ausgabe:

finalList = [{"Name":'Nick','Hour':0,'Value':4.96}, 
     {"Name":'Sam','Hour':1,'Value':7.0}, 
     {'Name':'Val',"Hour":1,'Value':21.1}, 
     {'Name':'Nick','Hour':1,'Value':2.1}...] 
+4

'Summe (d [‚Value‘] für d in lst wenn d ['Name'] == 'Nick' und d ['Hour'] == 0) ' – Julien

+0

Überprüfen Sie die Änderungen bitte. Ich will es für alle Stunden und für alle Namen tun, danke :) – Blabber

+0

Siehe meine neue Antwort. – Julien

Antwort

2
[{'Name':name, 'Hour':hour, 'Value': sum(d['Value'] for d in lst if d['Name']==name and d['Hour']==hour)} for hour in hours for name in names] 

wenn Sie nicht bereits alle Namen haben und Stunden in Listen (oder Mengen) können Sie sie so erhalten:

names = {d['Name'] for d in lst} 
hours= {d['Hour'] for d in lst} 
+0

ungültig sind Syntax ungültig. – Blabber

+0

Behoben (hoffentlich :) – Julien

5

betrachten Pandas Modul - es ist sehr komfortabel für solche Datensätze:

import pandas as pd 

In [109]: lst 
Out[109]: 
[{'Hour': 0, 'Name': 'Nick', 'Value': 2.75}, 
{'Hour': 1, 'Name': 'Sam', 'Value': 7.0}, 
{'Hour': 0, 'Name': 'Nick', 'Value': 2.21}, 
{'Hour': 1, 'Name': 'Val', 'Value': 10.1}, 
{'Hour': 1, 'Name': 'Nick', 'Value': 2.1}] 

In [110]: df = pd.DataFrame(lst) 

In [111]: df 
Out[111]: 
    Hour Name Value 
0  0 Nick 2.75 
1  1 Sam 7.00 
2  0 Nick 2.21 
3  1 Val 10.10 
4  1 Nick 2.10 

In [123]: df.groupby(['Name','Hour']).sum().reset_index() 
Out[123]: 
    Name Hour Value 
0 Nick  0 4.96 
1 Nick  1 2.10 
2 Sam  1 7.00 
3 Val  1 10.10 

Export in das CSV:

df.groupby(['Name','Hour']).sum().reset_index().to_csv('/path/to/file.csv', index=False) 

Ergebnis:

Name,Hour,Value 
Nick,0,4.96 
Nick,1,2.1 
Sam,1,7.0 
Val,1,10.1 

wenn Sie es als ein Wörterbuch haben:

In [125]: df.groupby(['Name','Hour']).sum().reset_index().to_dict('r') 
Out[125]: 
[{'Hour': 0, 'Name': 'Nick', 'Value': 4.96}, 
{'Hour': 1, 'Name': 'Nick', 'Value': 2.1}, 
{'Hour': 1, 'Name': 'Sam', 'Value': 7.0}, 
{'Hour': 1, 'Name': 'Val', 'Value': 10.1}] 

können Sie viele ausgefallene Dinge tun Pandas mit:

In [112]: df.loc[(df.Name == 'Nick') & (df.Hour == 0), 'Value'].sum() 
Out[112]: 4.96 


In [121]: df.groupby('Name')['Value'].agg(['sum','mean']) 
Out[121]: 
     sum  mean 
Name 
Nick 7.06 2.353333 
Sam 7.00 7.000000 
Val 10.10 10.100000 
+0

Danke, aber ich möchte es zu allen Zeiten und für alle Namen tun können. Das ist der Punkt. – Blabber

+0

@Blabber, ich habe meine Antwort aktualisiert - ist das was du willst? – MaxU

+0

Es funktioniert. Ich versuche, es in CSV zu exportieren. df.to_csv (Dateiname, sep = '\ t')? – Blabber

3

Sie können mit beliebigem (hashable) Objekt als Schlüssel für einen Python-Wörterbuch, so dass nur ein Tupel verwenden Namen und Stunde als Schlüssel enthält:

from collections import defaultdict 
d = defaultdict(float) 
for item in lst: 
    d[(item['Name'], item['Hour'])] += item['Value'] 
Verwandte Themen