2017-09-23 815 views
1

我在跨整個字典進行迭代時遇到問題,無法對鍵的值中的每個元素進行簡單的彙總統計(平均值)。Python - 字典中各個鍵的每個值的均值

我的字典由那些號碼清單鍵和值:

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} 

感謝您的幫助所需的輸出!

+1

你能說出你期望得到'test_dict'的結果嗎? – mkrieger1

+0

@ Jean-FrançoisFabre我懷疑40應該是20,10和90的平均值,所以期望的結果可能是5個數字的列表,而不是帶有3個鍵的字典。 – mkrieger1

+0

你說得對 - 所需的輸出是一個包含5個鍵值對的字典。第一個將是位置1:40 –

回答

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平均是錯誤的。

+0

謝謝 - 我的真實願望,正如現在更好地解釋的,是爲每個值的每個第一個元素求平均值。請參閱所需的輸出 - 感謝您的幫助。 –

+1

@Tony,檢查編輯 –

+0

我對這個解決方案的保留意見是,它使用整數索引來遍歷數據,這不像Pythonic那樣。但它有效,它有效地回答了這個問題。 – fralau

1

不知道你的錯誤在哪裏,但是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} 
+0

謝謝 - 這是一個很好的方式來做到這一點。但是,我希望的輸出是獲取鍵的每個元素的平均值。請參閱編輯所需的輸出。 –

+0

檢查我的更新解決方案。仍然是一個班輪 –

1

你可以這樣做:

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} 
+0

謝謝,感謝您的幫助。期望的輸出實際上是不同的 - 我現在在原始文章中更好地解釋它。 –

+0

@Tony數組總是有5的固定長度嗎? –

+0

在這種情況下,是的。 –

1

爲了保持儘可能簡單,我我建議:

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_ +索引號? (如果是,爲什麼不把它放在列表中?)

有關平均函數,請參閱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

+0

謝謝 - 正如現在所解釋的,我真正的願望是獲得每個值中每個第一個元素的平均值。請參閱所需的輸出 - 感謝您的幫助。 –

+0

好的。這更容易。我會修改我的答案。 – fralau

+0

好的,謝謝。 –

相關問題