Python 如何让减速器根据键类型发出

Python 如何让减速器根据键类型发出,python,hadoop,mapreduce,reduce,Python,Hadoop,Mapreduce,Reduce,作为问题的后续,我有一个映射器,它将遍历大量数据,并将ID号作为值为1的键发出。每个关键点都有两个部分,由管道分隔符分隔,例如: 映射器发射: a|abc1 b| efg 1 a| cba 1 a|abc1 b| dhh 1 b| dhh 1 我要做的是让Reducer解析键,对于类型为“a”,即“a | abc”的每个键,我希望Reducer只发出重复的键,但是对于每一个其他类型(例如类型“b”,即“b | abc”),我希望Reducer发出所有键,即使值只有1 因此,上述数据将产生: a|

作为问题的后续,我有一个映射器,它将遍历大量数据,并将ID号作为值为1的键发出。每个关键点都有两个部分,由管道分隔符分隔,例如:

映射器发射:
a|abc1
b| efg 1
a| cba 1
a|abc1
b| dhh 1
b| dhh 1

我要做的是让Reducer解析键,对于类型为“a”,即“a | abc”的每个键,我希望Reducer只发出重复的键,但是对于每一个其他类型(例如类型“b”,即“b | abc”),我希望Reducer发出所有键,即使值只有1

因此,上述数据将产生:
a|abc 2
b| efg 1
b| dhh 2

在这种情况下,不会发出“a | cba 1”,因为它是“a”类型的键,并且没有重复项。下面是我尝试过的代码,它的工作原理几乎和预期的一样,只是我得到了92个额外的发射,其中键的类型为“a”,计数为1。注意:92是根据我的MapReduce日志的Reduce任务数

由于我只需要密钥类型“a”的副本,我如何修复减速器,以便不获得值为1的密钥类型“a”的额外92次发射

import sys
import codecs

sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
inData = codecs.getreader('utf-8')(sys.stdin)

(last_key, tot_cnt) = (None, 0)
for line in inData:
    (key, val) = line.strip().split("\t")
    if last_key != key:
        k = key.split('|')
        v_id = k[0]
        if v_id == 'a':
            if tot_cnt > 1:
                sys.stdout.write("%s\t%s\n" % (last_key,tot_cnt))
        else:
            sys.stdout.write("%s\t%s\n" % (last_key,tot_cnt))

        (last_key, tot_cnt) = (key, int(val))
    else:
        (last_key, tot_cnt) = (key, tot_cnt + int(val))
if last_key:
    if v_id == 'a':
        if tot_cnt > 1:
            sys.stdout.write("%s\t%s\n" % (last_key, tot_cnt))
    else:
        sys.stdout.write("%s\t%s\n" % (last_key, tot_cnt))

以下是代码中的错误:

  • 在全局级别声明
    v_id
    ,以便它随处可见

    更改此行:

    (last_key, tot_cnt) = (None, 0)
    
    致:

  • 以下拆分应在
    最后一个_键
    上,而不是当前的
    。当当前键为“b | dhh”且最后一个键为“a | abc”时,您应该获得“a | abc”的
    v|u id

    更改此代码:

    if last_key != key:
        k = key.split('|')
        v_id = k[0]
    if v_id == 'a':
        if tot_cnt > 1:
            sys.stdout.write("%s\t%s\n" % (last_key,tot_cnt))
    else:
        sys.stdout.write("%s\t%s\n" % (last_key,tot_cnt))
    
    致:

  • 因此,修改后的reducer代码如下所示:

    import sys
    import codecs
    
    sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
    inData = codecs.getreader('utf-8')(sys.stdin)
    
    (last_key, tot_cnt, v_id) = (None, 0, None)
    
    for line in inData:
        (key, val) = line.strip().split("\t")
        if last_key != key:
            if last_key != None:
                k = last_key.split('|')
                v_id = k[0]
    
                if v_id == 'a':
                    if tot_cnt > 1:
                        sys.stdout.write("%s\t%s\n" % (last_key,tot_cnt))
                else:
                    sys.stdout.write("%s\t%s\n" % (last_key,tot_cnt))
    
            (last_key, tot_cnt) = (key, int(val))
        else:
            (last_key, tot_cnt) = (key, tot_cnt + int(val))
    
    if last_key:
        if v_id == 'a':
            if tot_cnt > 1:
                sys.stdout.write("%s\t%s\n" % (last_key, tot_cnt)) 
        else:
            sys.stdout.write("%s\t%s\n" % (last_key, tot_cnt))
    
    当我运行这个时,我得到了输出:

    a|abc   2
    b|dhh   2
    b|efg   1
    

    注意:我不是Python专家。我觉得,你可以优化这个代码。因此,请检查脚本中是否存在任何角落案例和冗余检查。

    我想,我知道问题所在。我将发布答案克里斯·尼尔森,我已经添加了答案。检查并确认它是否工作。
    import sys
    import codecs
    
    sys.stdout = codecs.getwriter('utf-8')(sys.stdout)
    inData = codecs.getreader('utf-8')(sys.stdin)
    
    (last_key, tot_cnt, v_id) = (None, 0, None)
    
    for line in inData:
        (key, val) = line.strip().split("\t")
        if last_key != key:
            if last_key != None:
                k = last_key.split('|')
                v_id = k[0]
    
                if v_id == 'a':
                    if tot_cnt > 1:
                        sys.stdout.write("%s\t%s\n" % (last_key,tot_cnt))
                else:
                    sys.stdout.write("%s\t%s\n" % (last_key,tot_cnt))
    
            (last_key, tot_cnt) = (key, int(val))
        else:
            (last_key, tot_cnt) = (key, tot_cnt + int(val))
    
    if last_key:
        if v_id == 'a':
            if tot_cnt > 1:
                sys.stdout.write("%s\t%s\n" % (last_key, tot_cnt)) 
        else:
            sys.stdout.write("%s\t%s\n" % (last_key, tot_cnt))
    
    a|abc   2
    b|dhh   2
    b|efg   1