2016-04-30 485 views
0

我有這個list由csv製成,這是一個巨大的。 對於list中的每個項目,我已將其分解爲它的iddetailsid始終在0-3個字符的最大長度之間,details是可變的。 我創建一個空的字典,d ...(下面的代碼休息):通過嵌套值的頻率排序嵌套字典

D={} 

for v in list: 

    id = v[0:3] 
    details = v[3:] 

    if id not in D: 
     D[id] = {} 

    if details not in D[id]: 
     D[id][details] = 0 

    D[id][details] += 1 

旁白:你能幫助我瞭解兩個if語句在做什麼? python和編程非常新。

無論如何,它會產生這樣的:

{'KEY1_1': {'key2_1' : value2_1, 'key2_2' : value2_2, 'key2_3' : value2_3}, 
'KEY1_2': {'key2_1' : value2_1, 'key2_2' : value2_2, 'key2_3' : value2_3}, 
and many more KEY1's with variable numbers of key2's 

每個 'KEY1' 是獨一無二的,但每個 '鍵2' 也不一定。 value2_ s都是不同的。

好了,所以,現在我發現了一種由第一KEY

for k, v in sorted(D.items()): 
    print k, ':', v 

我已經做了足夠的研究知道,字典不能真正進行排序,但我不關心排序進行排序,我關心訂購或更具體的發生頻率。在我的代碼value2_x中是其對應的key2_x發生在特定KEY1_x的次數。我開始認爲我應該使用更好的變量名稱。

問題:如何根據value2_x中嵌套字典中的數字來排列頂級/整體字典?我想對這些數字做一些統計...

  1. 最頻繁的KEY1_x:key2_x對出現多少次?
  2. 什麼是10,20,30最常見的KEY1_x:key2_x對?

我只能通過每個KEY1來做到這一點,還是我可以整體做到這一點?獎勵:如果我可以用這種方式爲了演示/分享而訂購,這將非常有用,因爲它是如此龐大的數據集。非常感謝,我希望我已經提出了我的問題和意圖。

回答

0

您可以使用Counter根據它們的頻率對密鑰對進行排序。它還提供了一種簡單的方法來獲得X最常見的項目:

from collections import Counter 

d = { 
    'KEY1': { 
     'key2_1': 5, 
     'key2_2': 1, 
     'key2_3': 3 
    }, 
    'KEY2': { 
     'key2_1': 2, 
     'key2_2': 3, 
     'key2_3': 4 
    } 
} 

c = Counter() 
for k, v in d.iteritems(): 
    c.update({(k, k1): v1 for k1, v1 in v.iteritems()}) 

print c.most_common(3) 

輸出:

[(('KEY1', 'key2_1'), 5), (('KEY2', 'key2_3'), 4), (('KEY2', 'key2_2'), 3)] 

如果你只關心最常見的密鑰對,並沒有其他理由建立嵌套的字典你可以只需使用下面的代碼:

from collections import Counter 

l = ['foobar', 'foofoo', 'foobar', 'barfoo'] 
D = Counter((v[:3], v[3:]) for v in l) 
print D.most_common() # [(('foo', 'bar'), 2), (('foo', 'foo'), 1), (('bar', 'foo'), 1)] 

簡短說明((v[:3], v[3:]) for v in l)generator expression是將生成tuples,其中第一項與原始dict中的頂級密鑰相同,第二項與嵌套dict中的密鑰相同。

>>> x = list((v[:3], v[3:]) for v in l) 
>>> x 
[('foo', 'bar'), ('foo', 'foo'), ('foo', 'bar'), ('bar', 'foo')] 

Counterdict一個子類。它接受iterable作爲參數,並且iterable中的每個唯一元素將用作鍵,值是iterable中元素的計數。

>>> c = Counter(x) 
>>> c 
Counter({('foo', 'bar'): 2, ('foo', 'foo'): 1, ('bar', 'foo'): 1}) 

由於generator expressionis an iterable沒有必要將它轉化成之間,建設可以簡單地用Counter((v[:3], v[3:]) for v in l)來完成列出英寸你問正在檢查

if語句,如果鑰匙dict存在:

>>> d = {1: 'foo'} 
>>> 1 in d 
True 
>>> 2 in d 
False 

所以下面的代碼將檢查與id價值關鍵在字典D存在,如果沒有它會在那裏指定空字典。

if id not in D: 
    D[id] = {} 

第二個if對於嵌套字典完全相同。

+0

感謝您的回覆 - 我看到它會生成一個列表,但我關心的值仍然卡在字典中?我想知道最常出現的KEY:密鑰對。謝謝你的第二個解釋 - 我想我明白了 - D [id]創建一個字典,其中'key'是'id','value'是空白的?不確定第二條陳述。 –

+0

@nrksj我已經根據澄清更新了答案。 – niemmi

+0

我不能夠感謝你!我玩過你的解決方案,並認爲它應該適用於我的實際數據集。我不知道是什麼促使像你這樣的人來幫助我們的新手,但我很欣賞它。現在感覺像是魔法,我會對你的代碼做更多的閱讀,但是你可以添加的任何評論/解釋都會很棒。標記此答案。 @niemmi –