按部门名称划分的女员工缩减代码
Reducer code for female employee by department name
我是 map-reduce 编码的新手。我请求帮助编写 reducer 代码,但找不到。按部门名称划分的女性员工人数。
我有两个结构化数据文件。一个给员工,另一个给部门。在员工档案中,我有 "Empid"、"Empname"、"Empgender"、"EmpDeptId" 和 "Empsalary"。在第二个部门文件中,我有 "DepId" 和 "DeptName"。现在我想通过每个部门名称找出 FEMALE 员工的数量。
我写了一个 EmpMapper,我在其中 return 将密钥设置为 DeptId (IntWritable) 而不是。出现次数,即迭代(作为文本)作为值。
例如
(1,[1])
(2,[1])
(3,[1])
(4,[1])
(1,[1])
在洗牌和排序阶段之后,输出如下:
(1,[1,1])
(2,[1])
(3,[1])
(4,[1])
我还从 DeptMapper return 输出以下输出(键作为 DeptId (IntWritable) 和 DeptName(作为文本)作为值):
(1,[IT])
(2,[Comsc])
(3,[Electrical])
(4,[Mechanical])
现在我担心的是我无法正确编写减速器。我想 return reducer 输出为
(IT,2)
(Comsc,1)
(Electrical,1)
(Mechanical,1)
请在 reducer 代码中帮助我(其中需要一种连接)。
在 MapReduce 中编写连接很麻烦。如果您已经拥有结构化(关系)数据,那么考虑一个高级框架可能是有意义的,例如 Hive,它允许您编写 SQL 查询。
如果您想为此使用 MapReduce,请查看 this post for reduce-side joins and this post for map-side joins。
这基本上是一个reduce端连接,在reducer端创建一个部门映射,并为每个员工使用这个映射获取每个员工的部门,然后主要是一个单独的数据结构来计数。
你的reducer有key = IntWritable, value = Text。因此,您可以轻松地将它们连接在一起,但是当您获得计数时,我会遇到类型问题(例如“1”、“1”以及部门名称 "IT")。
一个简单的方法是只检查您的文本是否为 int,如果遇到解析错误,您可以假设它是您的部门名称。
也许下面的代码(尽管有点老套)可能会帮助您找到解决方案:
@Override
protected void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
String departmentName = null;
int sum = 0;
for (Text value : values) {
String unknown = value.toString();
try {
int valueCount = Integer.parseInt(unknown);
sum += valueCount;
} catch (NumberFormatException e) {
departmentName = unknown;
}
}
assert departmentName != null;
context.write(new Text(departmentName), new IntWritable(sum));
}
我不喜欢使用异常来进行流量控制,但让我们在这里务实一点。
小工作改进:
- 您可以通过使用
MultipleInputs
类
- 以department-id为key,count+department name为value
- 做上面的减少
我是 map-reduce 编码的新手。我请求帮助编写 reducer 代码,但找不到。按部门名称划分的女性员工人数。
我有两个结构化数据文件。一个给员工,另一个给部门。在员工档案中,我有 "Empid"、"Empname"、"Empgender"、"EmpDeptId" 和 "Empsalary"。在第二个部门文件中,我有 "DepId" 和 "DeptName"。现在我想通过每个部门名称找出 FEMALE 员工的数量。
我写了一个 EmpMapper,我在其中 return 将密钥设置为 DeptId (IntWritable) 而不是。出现次数,即迭代(作为文本)作为值。 例如
(1,[1])
(2,[1])
(3,[1])
(4,[1])
(1,[1])
在洗牌和排序阶段之后,输出如下:
(1,[1,1])
(2,[1])
(3,[1])
(4,[1])
我还从 DeptMapper return 输出以下输出(键作为 DeptId (IntWritable) 和 DeptName(作为文本)作为值):
(1,[IT])
(2,[Comsc])
(3,[Electrical])
(4,[Mechanical])
现在我担心的是我无法正确编写减速器。我想 return reducer 输出为
(IT,2)
(Comsc,1)
(Electrical,1)
(Mechanical,1)
请在 reducer 代码中帮助我(其中需要一种连接)。
在 MapReduce 中编写连接很麻烦。如果您已经拥有结构化(关系)数据,那么考虑一个高级框架可能是有意义的,例如 Hive,它允许您编写 SQL 查询。
如果您想为此使用 MapReduce,请查看 this post for reduce-side joins and this post for map-side joins。
这基本上是一个reduce端连接,在reducer端创建一个部门映射,并为每个员工使用这个映射获取每个员工的部门,然后主要是一个单独的数据结构来计数。
你的reducer有key = IntWritable, value = Text。因此,您可以轻松地将它们连接在一起,但是当您获得计数时,我会遇到类型问题(例如“1”、“1”以及部门名称 "IT")。
一个简单的方法是只检查您的文本是否为 int,如果遇到解析错误,您可以假设它是您的部门名称。
也许下面的代码(尽管有点老套)可能会帮助您找到解决方案:
@Override
protected void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
String departmentName = null;
int sum = 0;
for (Text value : values) {
String unknown = value.toString();
try {
int valueCount = Integer.parseInt(unknown);
sum += valueCount;
} catch (NumberFormatException e) {
departmentName = unknown;
}
}
assert departmentName != null;
context.write(new Text(departmentName), new IntWritable(sum));
}
我不喜欢使用异常来进行流量控制,但让我们在这里务实一点。
小工作改进:
- 您可以通过使用
MultipleInputs
类- 以department-id为key,count+department name为value
- 做上面的减少