Python,从dict数组中收集数据
我是Python新手,我从DB实现了这种结构Python,从dict数组中收集数据,python,Python,我是Python新手,我从DB实现了这种结构 data=[ {'Value': '0.2', 'id': 1}, {'Value': '1.2', 'id': 1}, {'Value': '33.34', 'id': 2}, {'Value': '44.3', 'id': 3}, {'Value': '33.23', 'id': 3}, {'Value': '21.1', 'id': 4}, {'Value': '5.33', 'id': 4}, {'Value': '33.3', 'id':
data=[
{'Value': '0.2', 'id': 1},
{'Value': '1.2', 'id': 1},
{'Value': '33.34', 'id': 2},
{'Value': '44.3', 'id': 3},
{'Value': '33.23', 'id': 3},
{'Value': '21.1', 'id': 4},
{'Value': '5.33', 'id': 4},
{'Value': '33.3', 'id': 5},
{'Value': '12.2', 'id': 5},
{'Value': '1.22', 'id': 5},
{'Value': '1.23', 'id': 6}
]
我知道我可以通过以下方式获取记录的id:
data[i]['id']
但我需要在适当的数据结构中按ID收集数据,以便获得每个ID的平均值
什么是更好的选择
我在考虑为每个ID集构建一个新的dict,但是ID的数量可能会增加,我不知道如何解决这个问题。如果有人能给我一些建议,我将不胜感激。如果您有
numpy
,您可以轻松地使用它:
import numpy
numpy.mean([x['id'] for x in data])
否则,它将非常简单:
from __future__ import division # if python2.7
ids = [x['id'] for x in data]
print sum(ids)/len(ids)
您只需在收集完所有ID后创建ID列表:
id_list = [element['id'] for element in data]
从那里你可以计算你想要的任何东西。假设你的数据是按ID排序的,就像它出现在
数据
变量中一样,你可以尝试使用itertools.groupby
,可以指示它按ID
分组。然后,您可以创建一个新词典,该词典的键等于id
数字,值等于的意思
:
In [1]: from itertools import groupby
In [2]: data=[
...: {'Value': '0.2', 'id': 1},
...: {'Value': '1.2', 'id': 1},
...: {'Value': '33.34', 'id': 2},
...: {'Value': '44.3', 'id': 3},
...: {'Value': '33.23', 'id': 3},
...: {'Value': '21.1', 'id': 4},
...: {'Value': '5.33', 'id': 4},
...: {'Value': '33.3', 'id': 5},
...: {'Value': '12.2', 'id': 5},
...: {'Value': '1.22', 'id': 5},
...: {'Value': '1.23', 'id': 6}
...: ]
In [3]: means = {}
In [4]: for k, g in groupby(data, key=lambda x: x['id']):
...: g = list(g)
...: means[k] = sum(float(x['Value']) for x in g) / len(g)
...:
...:
In [5]: means
Out[5]:
{1: 0.69999999999999996,
2: 33.340000000000003,
3: 38.765000000000001,
4: 13.215,
5: 15.573333333333332,
6: 1.23}
(更新:在DSM的评论之后)
您可以按如下方式重塑数据:
from collections import defaultdict
data=[
{'Value': '0.2', 'id': 1},
{'Value': '1.2', 'id': 1},
{'Value': '33.34', 'id': 2},
{'Value': '44.3', 'id': 3},
{'Value': '33.23', 'id': 3},
{'Value': '21.1', 'id': 4},
{'Value': '5.33', 'id': 4},
{'Value': '33.3', 'id': 5},
{'Value': '12.2', 'id': 5},
{'Value': '1.22', 'id': 5},
{'Value': '1.23', 'id': 6}
]
newdata = defaultdict(list)
for r in data:
newdata[r['id']].append(float(r['Value']))
这将产生:
In [2]: newdata
Out[2]: defaultdict(<type 'list'>, {1: [0.2, 1.2], 2: [33.34], 3: [44.3, 33.23], 4: [21.1, 5.33], 5: [33.3, 12.2, 1.22], 6: [1.23]})
其中:
In [4]: mean
Out[4]: {1: 0.7, 2: 33.34, 3: 38.765, 4: 13.215, 5: 15.573333333333332, 6: 1.23}
我想这是一个显而易见的方法@DSM哈,因为我总是很难发现明显的方式,很高兴得到确认(尤其是你的:)。
mean
或average
可能比dict\u id
更好。您还可以使用collections.OrderedDict
来保留id顺序。@J.F.Sebastian Good point-变量命名从来都不是我的强项。现在将更新。命名是著名引用中的一个难题。但是(令人惊讶的是)事实表明(就我所知的一项研究而言,简短的人工代码示例)好的名字只会帮助有经验的程序员:新手程序员阅读代码的速度同样慢,无论它是否遵循好的命名约定。+1。不过有两位——首先,在newdata中不需要。keys():
,在newdata:
中就足够了。其次,如果您使用newdata=collections.defaultdict(list)
,那么if/else
是不必要的,您只需使用newdata[r['id']].append(val)
,并计算平均值:mean={id:sum(values)/len(values)for id,newdata.viewitems()}
@J.F.Sebastian:好的一点。最初我把它删掉了,因为我觉得它很琐碎。
In [4]: mean
Out[4]: {1: 0.7, 2: 33.34, 3: 38.765, 4: 13.215, 5: 15.573333333333332, 6: 1.23}