微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MapReduce(Python)-如何对Top-N列表的reducer输出进行排序?

我是MapReduce的新手.当前正在尝试完成Hadoop MapReduce上的udacity课程.

我有一个解析器来解析论坛节点,并且我将获得与每个节点关联的标签.我的目标是对前10个标签进行排序.

输出示例:

video   1
cs101   1
@R_404_5635@    1
bug     1
issues  1
nationalities   1
cs101   1
welcome 1
cs101   1
cs212   1
cs262   1
cs253   1
discussion      1
@R_404_5635@    1

将它们全部添加到reducer中非常容易:

#!/usr/bin/python

import sys
import string

total = 0
oldKey = None

for line in sys.stdin:
    data_mapped = line.strip().split("\t")

    if(len(data_mapped) != 2):
        print "====================="
        print line.strip()
        print "====================="
        continue

    key, value = data_mapped

    if oldKey and oldKey != key:
        print total, "\t", oldKey
        oldKey = key;
        total = 0

    oldKey = key
    total += float(value)

if oldKey != None:
    print total, "\t", oldKey

输出

1.0     application
1.0     board
1.0     browsers
1.0     bug
8.0     cs101
1.0     cs212
5.0     cs253
1.0     cs262
1.0     deadlines
1.0     digital
5.0     discussion
1.0     google-appengine
2.0     homework
1.0     html
1.0     hungarian
1.0     hw2-1
3.0     issues
2.0     jobs
2.0     lessons

我知道键在映射器的输出中排序,因此我只测试键是否仍然是相同的标签.如果不是,那么我将输出标记出现的次数.

但是,问题是如何对该列表进行排序?

如果我将所有信息存储在列表或字典中,则可以使用python对列表进行排序.但是,这似乎是一个错误的设计决策,因为如果您有很多不同的标签,则会耗尽内存.

解决方法:

我相信您可以在这里使用collections.Counter类:

示例:(从您的代码修改而来)

#!/usr/bin/python

import sys
import collections

counter = collections.Counter()

for line in sys.stdin:
    k, v = line.strip().split("\t", 2)

    counter[k] += int(v)

print counter.most_common(10)

collections.Counter()类实现了这个准确的用例以及许多其他的常见用例,涉及对事物进行计数并收集各种统计信息等.

8.3.1. Counter objects A counter tool is provided to support convenient and rapid tallies. For example:

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐