我有一个排序的二维列表,其中第一列中的特定值可以多次出现,但在第二列中有不同的对应值。
示例:
1 10
2 20
3 30
3 35
4 40
5 45
5 50
5 55
6 60
我想对这些多个条目进行平均,以便我的最终列表看起来像
1 10
2 20
3 32.5
4 40
5 50
6 60
一个问题是,您不知道值发生了多少次。到目前为止我的代码看起来像
for i in range(len(list)):
print i
if i+1 < len(list):
if list[i][0] == list[i+1][0]:
j = 0
sum = 0
while list[i][0] == list[i+j][0]: #this while loop is there to account for the unknown number of multiple values
sum += list[i+j][1]
j += 1
avg = sum / j
#print avg
#i+=j # here I try to skip the next j steps in the for loop, but it doesn't work
#final[i].append(i)
#final[i].append(avg) # How do I append a tuple [i, avg] to the final list?
else:
final.append(list[i])
else:
final.append(list[i])
print final
我的问题是:
答案 0 :(得分:2)
以下代码正在使用groupby
中的itertools
:
lst = [[1, 10],
[2, 20],
[3, 30],
[3, 35],
[4, 40],
[5, 45],
[5, 50],
[5, 55],
[6, 60],
]
from itertools import groupby
avglst = []
for grpname, grpvalues in groupby(lst, lambda itm: itm[0]):
values = [itm[1] for itm in grpvalues]
avgval = float(sum(values)) / len(values)
avglst.append([grpname, avgval])
print(avglst)
运行时:
$ python avglist.py (env: stack)
python[[1, 10.0], [2, 20.0], [3, 32.5], [4, 40.0], [5, 50.0], [6, 60.0]]
它提供了您要求的结果。
说明:
groupby
可迭代(列表)和一个函数,它计算名为key的值,即一个值,
用于创建组。在我们的例子中,我们将根据列表项中的第一个元素进行分组。
注意,groupby
每次键值更改时都会创建组,因此请确保输入列表是
排序,否则你得到的组数超出预期。
groupby
返回元组(grpname, groupvalues)
,其中grpname
是给定的关键值
group,groupvalues
是该组中所有项目的迭代器。小心,事实并非如此
列表,要从中获取列表,某些内容(如调用list(grpvalues)
)必须遍历值。
在我们的例子中,我们使用列表理解来迭代,每个列表元素中只选择第二项。
虽然python中的迭代器,生成器和类似结构起初可能看起来太复杂了, 他们目前服务非常好,必须处理非常大的列表和迭代。在这样的 例如,Python迭代器只在内存中保存当前项目,因此可以管理非常大或甚至 无休止的迭代。
答案 1 :(得分:1)
您可以使用字典计算左列中每个值出现的次数吗?还有一个单独的字典来映射与每个左边条目相关的元素总和。然后使用一个最终的for循环,将总和除以计数。
from collections import defaultdict
someList = [(1,10), (2,20), (3,30), (4,40), (5,45), (5,50), (5,55)]
count_dict = defaultdict(lambda:0)
sum_dict = defaultdict(lambda:0.0)
for left_val, right_val in someList:
count_dict[left_val] += 1
sum_dict[left_val] += right_val
for left_val in sorted(count_dict):
print left_val, sum_dict[left_val]/count_dict[left_val]
1 10.0
2 20.0
3 30.0
4 40.0
5 50.0
答案 2 :(得分:1)
首先,我们需要将列组合在一起。我们将使用字典,其中键是左列,值是该键的值列表。然后,我们可以进行简单的计算以获得平均值。
from collections import defaultdict
data = [
(1, 10),
(2, 20),
(3, 30),
(3, 35),
(4, 40),
(5, 45),
(5, 50),
(5, 55),
(6, 60)
]
# Organize the data into a dict
d = defaultdict(list)
for key, value in data:
d[key].append(value)
# Calculate the averages
averages = dict()
for key in d:
averages[key] = sum(d[key]) / float(len(d[key]))
# Use the averages
print(averages)
输出:
{1: 10.0, 2: 20.0, 3: 32.5, 4: 40.0, 5: 50.0, 6: 60.0}
答案 3 :(得分:1)
以下是Counter
和OrderedDict
组合的方法:
from __future__ import division # Python 2
from collections import Counter, OrderedDict
counts, sums = OrderedDict(), Counter()
for left, right in [(1,10), (2,20), (3,30), (4,40), (5,45), (5,50), (5,55)]:
counts[left] = counts.get(left, 0) + 1
sums[left] += right
result = [(key, sums[key]/counts[key]) for key in counts]