2016-04-30 115 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 –