对排序列表中的多个条目进行平均
average over multiple entries in a sorted list
我有一个排序的二维列表,其中第一列中的特定值可以出现多次,但第二列中的对应值不同。
示例:
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
我的问题是:
- 如何正确计算多个条目而不计算在内
他们用 for 循环两次?
- 如何将元组 [i, avg] 附加到最终列表?
您可以使用字典来计算左列中的每个值出现了多少次?和一个单独的字典来映射与每个左条目关联的元素的总和。然后用最后一个 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
首先我们需要将列组合在一起。我们将使用字典来完成此操作,其中键是左列,值是该键的值列表。然后,我们可以做一个简单的计算得到平均值。
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}
以下代码使用 itertools
中的 groupby
:
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
获取可迭代对象(列表)和一个函数,该函数计算称为键的 s,即一个值,
用于创建组。在我们的例子中,我们将根据列表项中的第一个元素进行分组。
请注意,每次键值更改时 groupby
都会创建组,因此请确保您的输入列表是
排序,否则你会得到比你预期更多的组。
groupby
returns 元组 (grpname, groupvalues)
其中 grpname
是给定的键值
组,groupvalues
是该组中所有项目的迭代器。小心,它不是
list,要从中获取列表,某些东西(比如调用 list(grpvalues)
)必须迭代这些值。
在我们的例子中,我们使用列表推导式进行迭代,只在每个列表元素中选择第二项。
虽然 python 中的迭代器、生成器和类似结构乍一看似乎过于复杂,
他们目前的服务非常好,必须处理非常大的列表和可迭代对象。在这样一个
在这种情况下,Python 迭代器仅在内存中保存当前项,因此可以管理非常大甚至
无尽的迭代。
以下是结合使用 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]
我有一个排序的二维列表,其中第一列中的特定值可以出现多次,但第二列中的对应值不同。
示例:
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
我的问题是:
- 如何正确计算多个条目而不计算在内 他们用 for 循环两次?
- 如何将元组 [i, avg] 附加到最终列表?
您可以使用字典来计算左列中的每个值出现了多少次?和一个单独的字典来映射与每个左条目关联的元素的总和。然后用最后一个 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
首先我们需要将列组合在一起。我们将使用字典来完成此操作,其中键是左列,值是该键的值列表。然后,我们可以做一个简单的计算得到平均值。
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}
以下代码使用 itertools
中的 groupby
:
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
获取可迭代对象(列表)和一个函数,该函数计算称为键的 s,即一个值,
用于创建组。在我们的例子中,我们将根据列表项中的第一个元素进行分组。
请注意,每次键值更改时 groupby
都会创建组,因此请确保您的输入列表是
排序,否则你会得到比你预期更多的组。
groupby
returns 元组 (grpname, groupvalues)
其中 grpname
是给定的键值
组,groupvalues
是该组中所有项目的迭代器。小心,它不是
list,要从中获取列表,某些东西(比如调用 list(grpvalues)
)必须迭代这些值。
在我们的例子中,我们使用列表推导式进行迭代,只在每个列表元素中选择第二项。
虽然 python 中的迭代器、生成器和类似结构乍一看似乎过于复杂, 他们目前的服务非常好,必须处理非常大的列表和可迭代对象。在这样一个 在这种情况下,Python 迭代器仅在内存中保存当前项,因此可以管理非常大甚至 无尽的迭代。
以下是结合使用 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]