我正在尝试编写mapreduce作业,我需要迭代两次值。
因此,当给出数字csv
文件时,我们需要为每列应用此文件。
为此,我们需要找到min
和max
值并将其应用于equation
(v1)。
到目前为止我做的是
In map()
I emit the column id as key and each column as values
In Reduce()
I calculated the min and max values of each column.
之后我被困住了。
接下来我的目标是apply
等式
(v = [(v − minA)/(maxA − minA)]*(new maxA − new minA ) + new minA )
我的new maxA and new minA is 0.1,0.0
,我也有每列max和min。
为了应用eqn v1我需要得到v,即输入文件。
如何获得?
我的想法是什么 -
从输入csv文件中取第一行(iris数据集)
[5.3,3.6,1.6,0.3]
为每个属性应用eqn并发出整行(Mincer和Max值在Reducer本身中是已知的)。但是在reducer中我只会得到列值。否则我应该将我的inputfile作为reducer()的setup()中的参数读取。
这是最佳做法吗? 任何建议。
更新
正如Mark Vickery
建议我做了以下内容。
public void reduce(Text key, Iterable<DoubleWritable> values, Context context) throws IOException,
InterruptedException {
System.out.println("in reducer");
double min = Integer.MAX_VALUE,max = 0;
Iterator<DoubleWritable> iterator = values.iterator();
ListIterator<DoubleWritable> lit = IteratorUtils.toListIterator(iterator);
System.out.println("Using ListIterator 1st pass");
while(lit.hasNext()){
System.out.println(lit.next());
DoubleWritable value = lit.next();
if (value.get()< min) {
min = value.get();
}
if (value.get() > max) {
max = value.get();
}
}
System.out.println(min);
System.out.println(max);
// move the list iterator back to start
while(lit.hasPrevious()){
lit.previous();
}
System.out.println("Using ListIterator 2nd pass");
double x = 0;
while(lit.hasNext()){
System.out.println(lit.next());
}
在第一遍中,我能够正确地获得所有值。但是对于第二遍,我只是重复获得每个元素。
答案 0 :(得分:1)
您可以在同一个reduce中对reducer值进行两次枚举。第一次计算最小值和最大值,第二次计算你的值,然后发出它。
粗略的例子:
public void Reduce(string key, List<string> values, Context context)
{
var minA = Min(values);
var maxA = Min(values);
foreach (var v in values)
{
var result = [(v − minA)/(maxA − minA)]*(new maxA − new minA ) + new minA;
context.Emit(result);
}
}
答案 1 :(得分:1)
我找到了答案。 如果我们尝试在Reducer中迭代两次,如下所示
ListIterator<DoubleWritable> lit = IteratorUtils.toListIterator(it);
System.out.println("Using ListIterator 1st pass");
while(lit.hasNext())
System.out.println(lit.next());
// move the list iterator back to start
while(lit.hasPrevious())
lit.previous();
System.out.println("Using ListIterator 2nd pass");
while(lit.hasNext())
System.out.println(lit.next());
我们只会输出
Using ListIterator 1st pass
5.3
4.9
5.3
4.6
4.6
Using ListIterator 2nd pass
5.3
5.3
5.3
5.3
5.3
为了以正确的方式得到它,我们应该像这样循环:
ArrayList<DoubleWritable> cache = new ArrayList<DoubleWritable>();
for (DoubleWritable aNum : values) {
System.out.println("first iteration: " + aNum);
DoubleWritable writable = new DoubleWritable();
writable.set(aNum.get());
cache.add(writable);
}
int size = cache.size();
for (int i = 0; i < size; ++i) {
System.out.println("second iteration: " + cache.get(i));
}
输出
first iteration: 5.3
first iteration: 4.9
first iteration: 5.3
first iteration: 4.6
first iteration: 4.6
second iteration: 5.3
second iteration: 4.9
second iteration: 5.3
second iteration: 4.6
second iteration: 4.6