【问题标题】:Python - Mean of each value across keys in dict [duplicate]Python - dict中键的每个值的平均值[重复]
【发布时间】:2017-09-23 17:43:01
【问题描述】:

我在遍历整个字典以对键中值的每个元素进行简单的汇总统计(平均值)时遇到问题。

我的字典由数字列表的键和值组成:

test_dict={'NJ':[20,50,70,90,100],'NY':[10,3,0,99,57],'CT':[90,1000,2,3.4,5]}

我知道我可以访问每个键的第一个值,例如,通过执行以下操作,但是我在明显的下一步添加另一个 for 循环以遍历值中的所有元素时遇到了麻烦。

location1=[element[0] for element in test_dict.values()] 
location1_avg=sum(location1)/len(location1)

我的最终目标是拥有一个以标签为键的字典(位置 1...i)以及该位置跨州的平均值。所以第一个键值是 Location1: 40,依此类推。

我有以下尝试,但错误消息是“列表索引超出范围”,我不知道在这种情况下如何正确迭代。

for element in test_dict.values():
    avg=list()
    for nums in element[i]:
        avg[i]=sum(element[i][nums])/len(element[i][nums])

为每个请求添加所需的输出

soln_dict={'Location1':40,'Location2':351,'Loction3':24,'Loction4':43.24,'Loction5':54}

感谢您的帮助!

【问题讨论】:

  • 您能否展示给定test_dict 的结果?
  • @Jean-FrançoisFabre 我怀疑 40 应该是 20、10 和 90 的平均值,因此所需的结果可能是 5 个数字的列表,而不是具有 3 个键的字典。跨度>
  • 你是对的 - 所需的输出是一个包含五个键值对的字典。第一个是位置 1:40

标签: python loops dictionary


【解决方案1】:

只要做:

#loop through the dictionary
for key,value in test_dict.items(): 

   #use reduce to calculate the avg
   print(key, reduce(lambda x, y: x + y, test_dict[key]) / len(test_dict[key]))

这将打印:

NJ 66.0
NY 33.8
CT 220.08

编辑:根据 OP 要求的变化:

l = list(iter(test_dict.values()))                      #convert values to list
print(l)
#[[20, 50, 70, 90, 100], [10, 3, 0, 99, 57], [90, 1000, 2, 3.4, 5]]
d={}                                                                  #final ditionary
for i in range(len(l[0])): 
   row_list = [row[i] for row in l]                     #get values column-wise
   d['location'+str(i+1)] = sum(row_list)/len(row_list)               #calculate avg

print(d)
#{'location1': 40.0, 'location2': 351.0, 'location3': 24.0, 'location4': 64.13333333333334, 'location5': 54.0}

注意:您提出的 loaction4 平均值是错误的。

【讨论】:

  • 谢谢 - 我的真正愿望,正如上面现在更好解释的那样,是获得每个值中每个第一个元素的平均值。请查看所需的输出 - 感谢您的帮助。
  • @Tony,检查编辑
  • 我对这个解决方案的保留意见是,它使用整数索引来循环数据,这不像 Python 那样。但它有效并且有效地回答了这个问题。
【解决方案2】:

你可以这样做:

test_dict={'NJ':[20,50,70,90,100],'NY':[10,3,0,99,57],'CT':[90,1000,2,3.4,5]}
avg=[sum(element) / len(element) for element in test_dict.values()]
print(avg) # => [66.0, 33.8, 220.08]

对于字典:

test_dict={'NJ':[20,50,70,90,100],'NY':[10,3,0,99,57],'CT':[90,1000,2,3.4,5]}
avg={ k:sum(test_dict[k]) / len(test_dict[k]) for k in test_dict}
print(avg) # => {'NJ': 66.0, 'NY': 33.8, 'CT': 220.08}

对已编辑问题的回答:

如果数组的长度总是 5,使用这个:

test_dict={'NJ':[20,50,70,90,100],'NY':[10,3,0,99,57],'CT':[90,1000,2,3.4,5]}
avg={}
for i in range(5):
  avg['Location'+str(i+1)] = sum(test_dict[k][i] for k in test_dict)/len(test_dict)
print(avg)

输出:

{'Location1': 40.0, 'Location2': 351.0, 'Location3': 24.0, 'Location4': 64.13333333333334, 'Location5': 54.0}

【讨论】:

  • 谢谢,感谢您的帮助。所需的输出实际上是不同的 - 我现在在原始帖子中解释得更好。
  • @Tony 数组的长度是否总是固定为 5?
  • 在这种情况下,是的。
  • @Tony 看看我编辑的答案是否有帮助。
  • 感谢您的帮助。
【解决方案3】:

不确定您的错误出在哪里,但 i 是“在无用/有害的地方使用索引”的致命赠品。

您的问题有一个直接的输入/输出数据流,非常适合使用字典理解、迭代键、值以及以均值作为值重建字典:

test_dict={'NJ':[20,50,70,90,100],'NY':[10,3,0,99,57],'CT':[90,1000,2,3.4,5]}

result = {k:sum(x)/len(x) for k,x in test_dict.items()}

print(result)

给予:

{'CT': 220.08, 'NJ': 66.0, 'NY': 33.8}

编辑:您似乎想要一个带有匿名键的“转置”版本,在这种情况下,只需使用值的压缩版本:

result = {"location{}".format(i):sum(v)/len(v) for i,v in enumerate(zip(*test_dict.values()),1)}

给予:

{'location3': 24.0, 'location5': 54.0, 'location1': 40.0, 'location2': 351.0, 'location4': 64.13333333333334}

【讨论】:

  • 谢谢 - 这是一个很好的方法。但是,我想要的输出是获取值的每个元素的键的平均值。请参阅编辑以获得所需的输出。
  • 检查我更新的解决方案。还是单线
【解决方案4】:

为了尽可能简单,我建议:

from statistics import mean

test_dict={'NJ':[20,50,70,90,100],'NY':[10,3,0,99,57],'CT':[90,1000,2,3.4,5]}

# put the data in a list of lists
# (throw away the city names)
l = [seq for seq in test_dict.values()]


# put together 1st values, 2nd values, etc.
r = [mean(i) for i in zip(*l)]
print(r)

这给出了:

[40, 351, 24, 64.13333333333334, 54]

我分而治之:我把这本字典变成了列表列表,然后用zip把“列”放在一起。由于 zip 需要用逗号而不是列表分隔的参数,因此我使用星号运算符 (*) 进行转换。

我不确定是否应该从那里获取地点列表?只是Location_ + 索引号吗? (如果是,为什么不把它放在一个列表中?)

对于 mean 函数,请参阅 statistics 包(适用于 Python > 3.4)。否则你可以自己写:

mean = lambda l: reduce(lambda x, y: x+y, l) / len(l)

我的灵感来自Finding the average of a list可能有点神秘,如果没有reduce,编写一个函数可能会更清楚,但是单行使其更容易复制和粘贴。

如果您使用的是 Python 3,请从 functools 导入 reduce

【讨论】:

  • 谢谢 - 我的真正愿望,正如上面现在更好解释的那样,是获得每个值中每个第一个元素的平均值。请查看所需的输出 - 感谢您的帮助。
  • 嗯,好的。这更容易。我会修改我的答案。
  • 其实,这并不是那么简单明了(我以为你只想要第一列的平均值)。
猜你喜欢
  • 2021-02-26
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 2022-06-23
  • 1970-01-01
  • 2011-03-25
  • 2020-01-17
  • 1970-01-01
相关资源
最近更新 更多