mapreduce计数差异
我正在尝试编写一个程序,输出2列中计数之间的差异。 所以我的数据看起来像这样:
2,1 2,3 1,2 3,1 4,2
我想计算col1中键的出现次数和col2中键的出现次数并取差。 输出应如下所示:
1,-1 2,0 3,0 4,1
这可以在一个mapreduce程序(mapper,reducer)中完成吗?
在每行的映射器中,您将创建两个键,一个用于col1,另一个用于col2,其中值从每列计数,如下所示:
2,1 – > 2:{1,0}和1:{0,1}
2,3 – > 2:{1,0}和3:{0,1}
1,2 – > 1:{1,0}和2:{0,1}
3,1 – > 3:{1,0}和1:{0,1}
4,2 – > 4:{1,0}和2:{0,1}
然后在reducer中,您将得到这些结果,其中每一行是每个reduce
调用的键和值组合:
1 – > {0,1},{1,0},{0,1}(添加它们会产生-1)
2 – > {1,0},2:{1,0},2:{0,1},2:{0,1}(添加它们将产生0)
3 – > {0,1},{1,0}(添加它们会产生0)
4 – > {1,0}(添加它们会产生1)
更新:
这是Hadoop示例(它未经过测试,可能需要进行一些调整才能使其正常工作):
public class TheMapper extends Mapper{ protected void map(LongWritable offset, Text value, Context context) throws IOException, InterruptedException { StringTokenizer tok = new StringTokenizer( value.toString(), "," ); Text col1 = new Text( tok.nextToken() ); context.write( col1, toArray(1, 0) ); Text col2 = new Text( tok.nextToken() ); context.write( col2, toArray(0, 1) ); } private ArrayPrimitiveWritable toArray(int v1, int v2){ return new ArrayPrimitiveWritable( new int[]{i1, i2} ); } } public class TheReducer extends Reducer { public void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException { Iterator i = values.iterator(); int count = 0; while ( i.hasNext() ){ int[] counts = (int[])i.next().get(); count += counts[0]; count -= counts[1]; } context.write( key, new Text("" + count) ); } }