对具有相等值的列表求和并聚合

时间:2014-07-18 11:12:12

标签: python list

我有一对长度相同的列表,第一个包含int值,第二个包含float值。我希望用另一对列表替换它们,这些列表可能更短,但仍然具有相同的长度,其中第一个列表仅包含唯一值,第二个列表将包含每个匹配值的总和。也就是说,如果新对中第一个列表的第i个元素为x,则x出现的原始对的第一个列表中的索引为i_1,...,i_k ,那么新对中第二个列表的第i个元素应该包含原始对的第二个列表中的索引i_1,...,i_k中的值的总和。

一个例子将澄清。

输入:

([1, 2, 2, 1, 1, 3], [0.1, 0.2, 0.3, 0.4, 0.5, 1.0])

可能输出:

([1, 2, 3], [1.0, 0.5, 1.0])

我试图在这里做一些列表理解技巧但失败了。我可以为此写一个愚蠢的循环函数,但我相信这里应该有更好的东西。

3 个答案:

答案 0 :(得分:3)

一种方法是使用pandas

>>> import pandas as pd
>>> df = pd.DataFrame({'tag':[1, 2, 2, 1, 1, 3], 
                       'val':[0.1, 0.2, 0.3, 0.4, 0.5, 1.0]})
>>> df
   tag  val
0    1  0.1
1    2  0.2
2    2  0.3
3    1  0.4
4    1  0.5
5    3  1.0
>>> df.groupby('tag')['val'].aggregate('sum')
tag
1      1.0
2      0.5
3      1.0
Name: val, dtype: float64

答案 1 :(得分:3)

不是单行,但由于您尚未发布解决方案,我建议使用collections.OrderedDict的此解决方案:

>>> from collections import OrderedDict
>>> a, b = ([1, 2, 2, 1, 1, 3], [0.1, 0.2, 0.3, 0.4, 0.5, 1.0])
>>> d = OrderedDict()
>>> for k, v in zip(a, b):
...     d[k] = d.get(k, 0) + v
...     
>>> d.keys(), d.values()
([1, 2, 3], [1.0, 0.5, 1.0])

当然,如果订单无关紧要,那么最好使用collections.defaultdict

>>> from collections import defaultdict
>>> a, b = ([1, 'foo', 'foo', 1, 1, 3], [0.1, 0.2, 0.3, 0.4, 0.5, 1.0])
>>> d = defaultdict(int)
>>> for k, v in zip(a, b):
    d[k] +=  + v
...     
>>> d.keys(), d.values()
([3, 1, 'foo'], [1.0, 1.0, 0.5])

答案 2 :(得分:1)

使用键构建地图:

la,lb = ([1, 2, 2, 1, 1, 3], [0.1, 0.2, 0.3, 0.4, 0.5, 1.0])
m = {k:0.0 for k in la}

并填写总结:

for i in xrange(len(lb)):
    m[la[i]] += lb[i]

最后,从你的地图:

zip(*[(k,m[k]) for k in m]*1)