2013-04-01 33 views
0

非常愚蠢的问题.. 我有数据如下查找意味着平均使用python的Hadoop流

id1, value 
1, 20.2 
1,20.4 
.... 

我想找到的均值和ID1的中间? (注..均值,中位数为每一个ID,而不是全球的平均数,中位数) 我使用python的hadoop streaming ..

mapper.py 
for line in sys.stdin: 
    try: 
    # remove leading and trailing whitespace 
     line = line.rstrip(os.linesep) 
     tokens = line.split(",") 

      print '%s,%s' % (tokens[0],tokens[1]) 
    except Exception: 
     continue 


reducer.py 
data_dict = defaultdict(list) 
def mean(data_list): 
    return sum(data_list)/float(len(data_list)) if len(data_list) else 0 
def median(mylist): 
    sorts = sorted(mylist) 
    length = len(sorts) 
    if not length % 2: 
     return (sorts[length/2] + sorts[length/2 - 1])/2.0 
    return sorts[length/2] 


for line in sys.stdin: 
    try: 
     line = line.rstrip(os.linesep) 
     serial_id, duration = line.split(",") 
     data_dict[serial_id].append(float(duration)) 
    except Exception: 
     pass 
for k,v in data_dict.items(): 
    print "%s,%s,%s" %(k, mean(v), median(v)) 

我期待一个平均数,中位数每个键 但我看到ID1重复使用不同平均数和中位数.. 例如..做的grep ..

mean_median/part-00003:SH002616940000,5.0,5.0 
mean_median/part-00008:SH002616940000,901.0,901.0 
mean_median/part-00018:SH002616940000,11.0,11.0 
mean_median/part-00000:SH002616940000,2.0,2.0 
mean_median/part-00025:SH002616940000,1800.0,1800.0 
mean_median/part-00002:SH002616940000,4.0,4.0 
mean_median/part-00006:SH002616940000,8.0,8.0 
mean_median/part-00021:SH002616940000,14.0,14.0 
mean_median/part-00001:SH002616940000,3.0,3.0 
mean_median/part-00022:SH002616940000,524.666666667,26.0  
mean_median/part-00017:SH002616940000,65.0,65.0 
mean_median/part-00016:SH002616940000,1384.0,1384.0 
mean_median/part-00020:SH002616940000,596.0,68.0  
mean_median/part-00014:SH002616940000,51.0,51.0 
mean_median/part-00004:SH002616940000,6.0,6.0 
mean_median/part-00005:SH002616940000,7.0,7.0 

有什么建议?

+0

默认情况下,Streaming使用制表符作为分隔符。你有没有设置它使用逗号? –

+0

是的..我想是的..我的意思是我使用的令牌= line.split(“,”)??所以它解析得很好? – Fraz

+0

不是一个愚蠢的问题,相信我。 :)任何需要全局状态的问题(如均值/中值)在Hadoop中都不是那么简单。 – Suman

回答

1

我在Hadoop的用户邮件列表回答同样的问题如下:

你没有多少减速开始这份工作? 如果你为这项工作启动了许多Reducers,它将产生多个输出文件,其命名为part-*。 而每个部分只是特定Reducer分区的本地平均值和中值。

两种解决方案: 1,调用setNumReduceTasks(1)的方法将Reducer编号设置为1,它只会产生一个输出文件,每个不同的密钥只会产生一个平均值和中值。 2,引用Hadoop源代码中的org.apache.hadoop.examples.WordMedian。它处理所有由多个Reducer通过本地函数生成的输出文件,并产生最终结果。