在Python中计算dict列表的平均值
我有一份每日价值清单,按顺序排列成一份清单,如下所示:在Python中计算dict列表的平均值,python,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,
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和集合的组合
{p:sum(map(lambda x:x[p],vals))/len(vals) for p in ['a','b','c']}
输出:
{'a': 5, 'c': 88, 'b': 15.143333333333333}
{'1': {'a': 11.666666666666666, 'c': 88.66666666666667, 'b': 15.143333333333333},
'2': {'a': 10.0, 'c': 2.0, 'b': 0.5}}
输出:
{'a': 5, 'c': 88, 'b': 15.143333333333333}
{'1': {'a': 11.666666666666666, 'c': 88.66666666666667, 'b': 15.143333333333333},
'2': {'a': 10.0, 'c': 2.0, 'b': 0.5}}
这可能比Elisha的答案略长,但中间数据结构较少,因此速度可能更快:
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}
这可能比Elisha的答案略长,但中间数据结构较少,因此速度可能更快:
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}
如果你有多个月的数据,熊猫会让你的生活更轻松:
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
如果你有多个月的数据,熊猫会让你的生活更轻松:
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
由于您希望按月计算平均值(此处考虑“dd-mm-yyyy”中的日期格式): 输出:
{'a': 5, 'c': 88, 'b': 15.143333333333333}
{'1': {'a': 11.666666666666666, 'c': 88.66666666666667, 'b': 15.143333333333333},
'2': {'a': 10.0, 'c': 2.0, 'b': 0.5}}
由于您希望按月计算平均值(此处考虑“dd-mm-yyyy”中的日期格式): 输出:
{'a': 5, 'c': 88, 'b': 15.143333333333333}
{'1': {'a': 11.666666666666666, 'c': 88.66666666666667, 'b': 15.143333333333333},
'2': {'a': 10.0, 'c': 2.0, 'b': 0.5}}
您是否确实阅读了您提到的模块的文档?一对导入将启用两个明显的简化。非主题:不要使用dict.has_key,它在Python3中被弃用并删除。使用:
如果p在val\u点:
另外,看看你写的代码实际上不起作用val_points=day[p]
将在第一次使用单个值替换dict,然后在下一次通过时引发异常,因为您试图将其用作dict…实际上,这里不需要任何模块。在dict
(试试help(dict)
看看你是否能找到它)上有一个方法,如果你试图写的东西乱七八糟的话,它会取代整个4行,但是你甚至不需要它,因为你可以从{'a':0,'b':0,'c':0}
或dict.from_-keys('abc',value=0)
开始。然后,没有理由不在生成器表达式传递给sum
时执行单独的循环,这是一个内置函数。(operator
可以让这一点更好一些,但这不是必需的。)您是否确实阅读了您提到的模块的文档?一对导入将启用两个明显的简化。非主题:不要使用dict.has_key,它在Python3中被弃用并删除。使用:如果p在val\u点:
另外,看看你写的代码实际上不起作用val_points=day[p]
将在第一次使用单个值替换dict,然后在下一次通过时引发异常,因为您试图将其用作dict…实际上,这里不需要任何模块。在dict
(试试help(dict)
看看你是否能找到它)上有一个方法,如果你试图写的东西乱七八糟的话,它会取代整个4行,但是你甚至不需要它,因为你可以从{'a':0,'b':0,'c':0}
或dict.from_-keys('abc',value=0)
开始。然后,没有理由不在生成器表达式传递给sum
时执行单独的循环,这是一个内置函数。(operator
可以让这一点更好一些,但这不是必要的。)我认为这不是OP想要的。他想要的是“一个月a、b和c的平均值”-对我来说,听起来像是每月一次。我以为他是指每个DICT列表都是一个月,他没有在自己的示例代码中拆分为几个月,他要求答案做同样的事情,我假设2014年2月1日是2月1日,2014年3月1日是3月1日,等等,但我明白你的意思。我想我们得让OP来启发我们。我的意思就是这样。忘记使用地图了,在rubyland呆了太久。我不认为这是OP要求的。他想要的是“一个月a、b和c的平均值”-对我来说,听起来像是每月一次。我以为他是指每个DICT列表都是一个月,他没有在自己的示例代码中拆分为几个月,他要求答案做同样的事情,我假设2014年2月1日是2月1日,2014年3月1日是3月1日,等等,但我明白你的意思。我想我们得让OP来启发我们。我的意思就是这样。忘记使用map了,在rubyland呆的时间太长了。'd'
密钥来自哪里?用于测试不存在的密钥。我的错误。我编辑了输出。'd'
键来自哪里?用于测试不存在的键。我的错误。我编辑了输出。