通过嵌套值的频率排序嵌套字典
我有这个list
由csv制成,这是一个巨大的。 对于list
中的每个项目,我已将其分解为它的id
和details
。 id
始终在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
中嵌套字典中的数字来排列顶级/整体字典?我想对这些数字做一些统计...
- 最频繁的KEY1_x:key2_x对出现多少次?
- 什么是10,20,30最常见的KEY1_x:key2_x对?
我只能通过每个KEY1
来做到这一点,还是我可以整体做到这一点?奖励:如果我可以用这种方式为了演示/分享而订购,这将非常有用,因为它是如此庞大的数据集。非常感谢,我希望我已经提出了我的问题和意图。
您可以使用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')]
Counter
是dict
一个子类。它接受iterable
作为参数,并且iterable
中的每个唯一元素将用作键,值是iterable
中元素的计数。
>>> c = Counter(x)
>>> c
Counter({('foo', 'bar'): 2, ('foo', 'foo'): 1, ('bar', 'foo'): 1})
由于generator expression
is 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
对于嵌套字典完全相同。
感谢您的回复 - 我看到它会生成一个列表,但我关心的值仍然卡在字典中?我想知道最常出现的KEY:密钥对。谢谢你的第二个解释 - 我想我明白了 - D [id]创建一个字典,其中'key'是'id','value'是空白的?不确定第二条陈述。 –
@nrksj我已经根据澄清更新了答案。 – niemmi
我不能够感谢你!我玩过你的解决方案,并认为它应该适用于我的实际数据集。我不知道是什么促使像你这样的人来帮助我们的新手,但我很欣赏它。现在感觉像是魔法,我会对你的代码做更多的阅读,但是你可以添加的任何评论/解释都会很棒。标记此答案。 @niemmi –