在reducer中获取输入文件

zpjtge22  于 2021-06-03  发布在  Hadoop
关注(0)|答案(2)|浏览(284)

我正在尝试编写一个mapreduce作业,其中需要迭代两次值。
所以当一个数字 csv 我们需要为每一列应用这个文件。
为此,我们需要找到 min 以及 max 值并将其应用于 equation (第1版)。
到目前为止我所做的是

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列。为了应用eqnv1,我需要得到v,即输入文件。
怎么弄到的?
我以为-
从输入csv文件获取第一行(iris数据集)

[5.3,3.6,1.6,0.3]

为每个属性应用eqn并发射整行(最小值和最大值在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());

}

第一遍我能正确地得到所有的值,但第二遍我只能重复得到每个元素的值。

iugsix8n

iugsix8n1#

可以在同一个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);
    }
}
1yjd4xko

1yjd4xko2#

我找到了答案。如果我们尝试在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

相关问题