Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 字典中重复的平均值_Python_Dictionary_Python 2.7 - Fatal编程技术网

Python 字典中重复的平均值

Python 字典中重复的平均值,python,dictionary,python-2.7,Python,Dictionary,Python 2.7,我正在用文本文件中的数据行制作字典。前三列数据构成键,第四列数据构成字典的值。其代码如下: def formatter(lines): for line in lines: if not line.strip(): continue yield [to_float(item) for item in line.split()] dct1 = {} with open('test.txt') as f1: for row in formatt

我正在用文本文件中的数据行制作字典。前三列数据构成键,第四列数据构成字典的值。其代码如下:

def formatter(lines):
    for line in lines:
        if not line.strip(): continue
        yield [to_float(item) for item in line.split()]

 dct1 = {}
 with open('test.txt') as f1:
     for row in formatter(f1):
        dct1[tuple(row[:3])] = row[3]
这个代码有效。问题在于,要从中提取数据的文件中存在密钥重复,例如,该文件可能有两行:

1  2  3  50
1  2  3  100
然而,最后一个字典dct1将只包含这些行中的第二行:dct1[(1,2,3)]=[100]。我正在尝试做的,但目前还不能做的是,每次程序试图覆盖一个键,而是平均给定键的值,也就是说,如果读入上述两行,键(1,2,3)的值将为75(平均值为50和100)

任何帮助都将不胜感激。
非常感谢

要计算多个键的平均值,您需要先收集所有值,然后再计算平均值

使用
collections.defaultdict
可以轻松收集值:

from collections import defaultdict

dct1 = defaultdict(list)

with open('test.txt') as f1:
    for row in formatter(f1):
       dct1[tuple(row[:3])].append(row[3])

dct1 = {k: sum(v)/len(v) for k, v in dct1.iteritems()}

首先,dct1是一个将键映射到值列表的字典。然后,dict理解将其替换为将键映射到平均值的字典。

要计算多个键的平均值,需要先收集所有值,然后计算平均值

使用
collections.defaultdict
可以轻松收集值:

from collections import defaultdict

dct1 = defaultdict(list)

with open('test.txt') as f1:
    for row in formatter(f1):
       dct1[tuple(row[:3])].append(row[3])

dct1 = {k: sum(v)/len(v) for k, v in dct1.iteritems()}

首先,dct1是一个将键映射到值列表的字典。然后,dict理解将其替换为一个字典,将键映射到平均值。

将前两个值平均后,找到第三个值会把你搞砸,因为你不知道dict中的值是单个值还是前两个值的平均值。您还需要在dict中保留计数:

for row in formatter(f1):
    key = tuple(row[:3])
    if key not in dct1:
        dct1[key] = (1, row[3])
    else:
        val = dct1[key]
        dct1[key] = (val[0] + 1, (val[0] * val[1] + row[:3]) / (val[0] + 1))

现在,dict中的每个元素都有一个计数和一个平均值。不要使用dct1[key],你必须使用dct1[key][1]。

一旦你对前两个取平均值,找到第三个会把你搞砸,因为你不知道dict中的值是单个值还是前两个值的平均值。您还需要在dict中保留计数:

for row in formatter(f1):
    key = tuple(row[:3])
    if key not in dct1:
        dct1[key] = (1, row[3])
    else:
        val = dct1[key]
        dct1[key] = (val[0] + 1, (val[0] * val[1] + row[:3]) / (val[0] + 1))


现在,dict中的每个元素都有一个计数和一个平均值。您必须使用dct1[key][1],而不是使用dct1[key][1]。

如果该键出现3次或更多次,该怎么办?还是平均水平吗?是的。数据集中有不同数量的重复,这会使解决方案复杂化。我发现这会使解决方案更简单,请参见下面的答案。如果密钥出现3次或更多次,该怎么办?还是平均水平吗?是的。数据集中的重复次数不一,这会使解决方案复杂化。我发现这会使解决方案更简单,请参见下面的答案。之后,您必须再次删除计数。最好在事后计算平均值,因为无论如何你都必须再次循环所有条目。只有当你需要最终的dict与他指定的完全一致时。无论是你的方式(元组的dict)还是我的方式,只要构建一个包含他想要的信息的dict,他就必须以不同的方式检索它。我的是一个简单的[1],你的是通过计算平均值。我的更快,你的可能更不可能累积舍入误差。当然,公平的说,如果OP愿意容忍小的舍入误差和输出中的额外数据,这是一个公平的解决方案。然后你必须再次删除计数。最好在事后计算平均值,因为无论如何你都必须再次循环所有条目。只有当你需要最终的dict与他指定的完全一致时。无论是你的方式(元组的dict)还是我的方式,只要构建一个包含他想要的信息的dict,他就必须以不同的方式检索它。我的是一个简单的[1],你的是通过计算平均值。我的更快,而你的可能更不容易累积舍入错误。当然,公平的说,如果OP愿意容忍小的舍入错误和输出中的额外数据,这是一个公平的解决方案。在这段代码的最后一行中,我一直得到:TypeError:“float”对象不是iterable@user1171835:那没有道理。你能在那一行之前插入一个
print dict1[dict1.keys()[0]]
,告诉我你现在有什么类型的值吗?@user1171835:那么你没有运行我的代码,或者你正在应用列表行两次。你已经在下面的答案中发布了我现在拥有的完整代码。将在以后删除它,以便不以任何方式取得它的信用@user1171835:缺少
.append(第[3]行]
部分。您正在替换由
defaultdict
提供的
列表,而不是将
float
添加到列表中。在此代码的最后一行中,我一直得到:TypeError:“float”对象不是iterable@user1171835:那没有道理。你能在那一行之前插入一个
print dict1[dict1.keys()[0]]
,告诉我你现在有什么类型的值吗?@user1171835:那么你没有运行我的代码,或者你正在应用列表行两次。你已经在下面的答案中发布了我现在拥有的完整代码。将在以后删除它,以便不以任何方式取得它的信用@user1171835:缺少
.append(第[3]行]
部分。您正在替换由
defaultdict
提供的
列表,而不是向其中添加
float