我从一堆或电子邮件中读取数据并计算每个单词的频率。首先构建两个计数器:
counters.stats = collections.defaultdict(dict)
counters.chi = collections.counter()
统计数据的关键是单词。对于每个单词,我构造一个dict,其键是电子邮件的名称,值是此电子邮件中该单词的频率。
chi的关键词与统计数据中的词相同。我想通过“chi”中的键对'stats'中的键进行排序。问题由以下方法解决:
def print_stats(counters):
sorted_key = sorted(counters.stats, key = counters.chi.get)
result = collections.OrderedDict(k, counters.stats[k] for key in sorted_key)
for form, cat_to_stats in result.items():
答案 0 :(得分:3)
如果我理解正确,这应该做你想要的:
>>> stats = {'a': {'email1':4, 'email2':3},
... 'the': {'email1':2, 'email3':4},
... 'or': {'email1':2, 'email3':1}}
>>> chi = {'a': 7, 'the':6, 'or':3}
>>> sorted(stats, key=chi.get)
['or', 'the', 'a']
如果这对您有用,请告诉我。另外,正如上面提到的Boud,您应该考虑numpy
/ scipy
,这可能会提供更好的性能 - 并且肯定会提供许多内置功能。</ p>
因为你说这不起作用 - 由于你还没有解释的原因 - 这里是一个更一般的例子,说明如何使用key
参数。这表明get
可以使用Counter
个对象以及标准的dicts,还可以创建一个可以执行某些操作的函数:
>>> stats = {'a': {'email1':4, 'email2':3},
... 'the': {'email1':2, 'email3':4},
... 'or': {'email1':2, 'email3':1}}
>>> wordlists = ([k] * sum(d.itervalues()) for k, d in stats.iteritems())
>>> chi = collections.Counter(word for seq in wordlists for word in seq)
>>> sorted(stats, key=chi.get)
['or', 'the', 'a']
>>> sorted(stats, key=lambda x: chi[x] + 3)
['or', 'the', 'a']
>>> sorted(stats, key=chi.get, reverse=True)
['a', 'the', 'or']
我仍然不完全理解你在寻找什么,但也许你的意思是得到一个关键的值元组的排序列表?
>>> sorted(stats.iteritems(), key=lambda x: chi[x[0]])
[('or', {'email3': 1, 'email1': 2}),
('the', {'email3': 4, 'email1': 2}),
('a', {'email2': 3, 'email1': 4})]
我实际上会建议拆分它:
>>>> sorted_keys = sorted(stats, key=chi.get)
>>>> [(k, stats[k]) for k in sorted_keys]
[('or', {'email3': 1, 'email1': 2}), ('the', {'email3': 4, 'email1': 2}), ('a', {'email2': 3, 'email1': 4})]
你说你希望按照chi
中的值排序,但“与stats具有相同的结构。”这是不可能的,因为词典没有订单;你可以得到的最接近的是元组的排序列表,或OrderedDict
(在2.7 +中)。
>>>> collections.OrderedDict((k, stats[k]) for k in sorted_keys)
OrderedDict([('or', {'email3': 1, 'email1': 2}), ('the', {'email3': 4, 'email1': 2}), ('a', {'email2': 3, 'email1': 4})])
如果你经常重新排序字典,这种方法毫无意义。