[英]Averaging a list of dicts in Python
我已經將每日值列表按順序排列成字典,如下所示:
vals = [
{'date': '1-1-2014', 'a': 10, 'b': 33.5, 'c': 82, 'notes': 'high repeat rate'},
{'date': '2-1-2014', 'a': 5, 'b': 11.43, 'c': 182, 'notes': 'normal operations'},
{'date': '3-1-2014', 'a': 0, 'b': 0.5, 'c': 2, 'notes': 'high failure rate'},
...]
我想做的是獲得該月的平均a,b和c。
是否有比做類似的更好的方法:
val_points = {}
val_len = len(vals)
for day in vals:
for p in ['a', 'b', 'c']:
if val_points.has_key(p):
val_points += day[p]
else:
val_points = day[p]
val_avg = dict([(i, val_points[i] / val_len] for p in val_points])
我沒有運行上面的代碼,可能會有故障,但是我希望我能理解。 我知道使用運算符,itertools和collection的某種組合可能是更好的方法。
{p:sum(map(lambda x:x[p],vals))/len(vals) for p in ['a','b','c']}
輸出:
{'a': 5, 'c': 88, 'b': 15.143333333333333}
這可能比以利沙的答案稍長,但是中間數據結構較少,因此可能更快:
KEYS = ['a', 'b', 'c']
def sum_and_count(sums_and_counts, item, key):
prev_sum, prev_count = sums_and_counts.get(key, (0,0)) # using get to have a fall-back if there is nothing in our sums_and_counts
return (prev_sum+item.get(key, 0), prev_count+1) # using get to have a 0 default for a non-existing key in item
sums_and_counts = reduce(lambda sc, item: {key: sum_and_count(sc, item, key) for key in KEYS}, vals, {})
averages = {k:float(total)/no for (k,(total,no)) in sums_and_counts.iteritems()}
print averages
輸出 :
{'a': 5.0, 'c': 88.66666666666667, 'b': 15.143333333333333}
如要按月計算平均值(此處考慮“ dd-mm-yyyy”中的日期格式):
vals = [
{'date': '1-1-2014', 'a': 10, 'b': 33.5, 'c': 82, 'notes': 'high repeat rate'},
{'date': '2-1-2014', 'a': 5, 'b': 11.43, 'c': 182, 'notes': 'normal operations'},
{'date': '3-1-2014', 'a': 20, 'b': 0.5, 'c': 2, 'notes': 'high failure rate'},
{'date': '3-2-2014', 'a': 0, 'b': 0.5, 'c': 2, 'notes': 'high failure rate'},
{'date': '4-2-2014', 'a': 20, 'b': 0.5, 'c': 2, 'notes': 'high failure rate'}
]
month = {}
for x in vals:
newKey = x['date'].split('-')[1]
if newKey not in month:
month[newKey] = {}
for k in 'abc':
if k in month[newKey]:
month[newKey][k].append(x[k])
else:
month[newKey][k] = [x[k]]
output = {}
for y in month:
if y not in output:
output[y] = {}
for z in month[y]:
output[y][z] = sum(month[y][z])/float(len(month[y][z]))
print output
輸出:
{'1': {'a': 11.666666666666666, 'c': 88.66666666666667, 'b': 15.143333333333333},
'2': {'a': 10.0, 'c': 2.0, 'b': 0.5}}
如果您有多個月的數據,熊貓將使您的生活更加輕松:
df = pandas.DataFrame(vals)
df.date = [pandas.datetools.parse(d, dayfirst=True) for d in df.date]
df.set_index('date', inplace=True)
means = df.resample('m', how='mean')
結果是:
a b c
date
2014-01-31 5 15.143333 88.666667
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.