基于键名的元组平均列表?
Posted
技术标签:
【中文标题】基于键名的元组平均列表?【英文标题】:Averaging list of tuples based on key name? 【发布时间】:2020-12-19 06:45:22 【问题描述】:modifiedL = [('10-1984', 2.8), ('10-1984', 2.8), ('10-1984', 2.85), ('10-1984', 2.82), ('10-1984', 2.78), ('10-1984', 2.75), ('09-1984', 2.82), ('09-1984', 2.9), ('09-1984', 2.9), ('09-1984', 2.94), ('09-1984', 2.99), ('09-1984', 3.02), ('09-1984', 3.05), ('09-1984', 3.04), ('09-1984', 3.11), ('09-1984', 3.22), ('09-1984', 3.13), ('09-1984', 3.09), ('09-1984', 2.94), ('09-1984', 3.02), ('09-1984', 2.97), ('09-1984', 2.98)]
avg=
for date, value in modifiedL:
avg.setdefault(date, []).append(value)
for key, value in avg.items():
avg[key] = sum(value)/float(len(value))
第一次循环后:
avg = '10-1984': [2.8, 2.81, 2.78, 2.77, 2.84, 2.95, 2.92, 2.85, 2.88, 2.88, 2.8, 2.68, 2.7, 2.56, 2.67, 2.68, 2.77, 2.8, 2.8, 2.85, 2.82, 2.78, 2.75], '09-1984': [2.82, 2.9, 2.9, 2.94, 2.99, 3.02, 3.05, 3.04, 3.11, 3.22, 3.13, 3.09, 2.94, 3.02, 2.97, 2.98]
第二次循环后:
avg= '10-1984': average, '09-1984': average
有没有办法简化代码或在一行中执行?
【问题讨论】:
你确定5559408.695652174
是列表的平均值,所有值都在 2 到 3 之间?
不是,它只是列表中的一个 sn-p,因为它很大
【参考方案1】:
您的代码很好。您可以替换其中的某些部分(例如使用 defaultdict
或 statistics.mean
),但仍需要 2 个循环。没有实际的理由让每个代码都单行,最好只创建一个具有好名称的函数。
但是,有一些选项可以使它成为单线。您可以使用itertools.groupby
(请注意,这会将算法复杂度增加到 O(N log N):
In [11]: from itertools import groupby
In [12]: from operator import itemgetter
In [13]: from statistics import mean
In [14]: k: mean(map(itemgetter(1), v)) for k, v in groupby(sorted(modifiedL, key=itemgetter(0)), key=itemgetter(0))
Out[14]: '09-1984': 3.0075, '10-1984': 2.8
您可以编写您的 groupby 版本,它不需要对序列进行排序以将复杂性降低回 O(N)(参见 this answer 示例)
或者,如果您在项目中使用 pandas,您可以将列表转换为 DataFrame:
In [29]: import pandas as pd
In [30]: df = pd.DataFrame(modifiedL)
In [31]: df.groupby(0).mean()
Out[31]:
1
0
09-1984 3.0075
10-1984 2.8000
【讨论】:
以上是关于基于键名的元组平均列表?的主要内容,如果未能解决你的问题,请参考以下文章