Python mapper reducer

时间:2015-04-07 05:23:04

标签: python hadoop

我是python的新手,无法弄清楚为什么这段代码不会产生错误消息而且没有输出。它读取Web日志文件。

def mapper(key, line):
    parts = line.split("/")
    if len(parts) > 2:
        return parts[1], 1
    return None, 1

def reducer(key, values):
    return key, sum(values)

def main():
    data = {key,values}
    with open('apache.log', 'r') as logfile:
        for idx, line in enumerate(logfile):
            line = line.strip()
            key, val = mapper(idx, line)
            if key in data:
                data[key].append(val)
            else:
                data[key] = [val,]
        for key, values in data.items():
            print reducer(key, values)

日志文件:

[31/Dec/1994:23:46:48 -0700] "GET 116.gif HTTP/1.0" 200 12053
remote - - [31/Dec/1994:23:50:42 -0700] "GET 2196.ps HTTP/1.0" 200 73941
remote - - [31/Dec/1994:23:55:08 -0700] "GET 45.html HTTP/1.0" 200 5489
remote - - [31/Dec/1994:23:56:55 -0700] "GET 2195.ps HTTP/1.0" 200 522318
remote - - [31/Dec/1994:23:59:37 -0700] "GET 957.ps HTTP/1.0" 200 122146
remote - - [01/Jan/1995:00:31:54 -0700] "GET index.html HTTP/1.0" 200 2797
remote - - [01/Jan/1995:00:31:58 -0700] "GET 2.gif HTTP/1.0" 200 2555

2 个答案:

答案 0 :(得分:2)

添加

main()

或更正式:

if __name__ == '__main__':
    main()

在源代码的末尾再次运行。

答案 1 :(得分:0)

正如flycee指出的那样,您似乎正在运行此代码。 (或者您是否只是将通话发送到main?)

您还有其他问题...... main的第一行:

data = {key,values}

您明确希望data成为字典,因此逗号应为冒号:{key: values}

更大的问题是set / dictionary --- keyvalues ---中的两个变量尚未定义。如果它被执行,这将引发UnboundLocalError

其他问题......

  • main中,将idx设置为日志文件的行号(0-indexed),并将其作为mapper参数传递给keymapper永远不会使用key参数,因此您可以有效地创建idx值,只是为了扔掉它。

  • reducer同样不使用其key参数,但至少它不会完全抛弃它。尽管如此,没有理由将main key reducer提供给mapper只是为了让它保持不变。

  • None返回一个"",稍后将其用作字典中的键,否则只能使用字符串键入。要么返回一个空字符串(None)来代替is not None,要么---更好的是---在将其添加到字典之前确保返回值"May"。您说您希望将"Dec"mapper计算好几个月...所以不要在所有非月份中污染您的数据。

  • 1返回两个值的元组,其中只有一个值感兴趣。第二个值始终为1,即使在mapper找不到任何内容的情况下,也无法设想 a "Jan" ....所以只需返回有趣的部分:字符串"Oct"sum或其他。

  • 如果您事先知道每个元素都是1,那么在成千上万个元素的列表中使用len是过度的。请改用len

  • 如果事先知道列表存在 来计算某些内容,则在成千上万个元素的列表中使用int是过度的。用一个 而是mapper

  • 当Python标准库已经免费提供给你一个时,从几个不同的函数实现一个计数器是过度的。请改用collections.Counter

最后的狡辩:您的reducer并未真正映射任何内容,而sum中唯一的缩减是内置mapper功能。那么为什么不调用month_logged更有意义的内容,例如reducer,并将sum完全替换为{{1}}?