2014-02-25 58 views
0

我想写一个mapreduce作业,我需要迭代两次值。获取Reducer输入文件

因此,当给出数字csv文件时,我们需要为每列应用此文件。

为此,我们需要找到minmax值并将其应用于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分别和我也有各列最大值和最小值。 为了应用eqn v1我需要v,即输入文件。

如何获得?

我想是 -

从输入csv文件采取的第一行(虹膜数据集)

[5.3,3.6,1.6,0.3] 

申请等式为每个属性和发射整行(Min和Max值在已知的减速机本身)。但在reducer中,我只会得到列值。否则,我应该读取我的输入文件作为reducer()的setup()中的参数。

这是最佳实践。 任何建议。

UPDATE

由于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()); 

} 

在1日通过我能够让所有的值correctly.But 2次经过我只反复得到每个元素。

+0

抱歉,我不得不去睡觉。我今天早上再次测试了'ListIterator',它工作正常。您能否将小代码转换为独立的运行代码并在ideone.com Java编辑器上重现问题? – anubhava

+0

但它不适用于我anubhava :(。我试着更多。我得到相同的输出。任何其他的替代方法? –

+0

@anubhava:即使我只是迭代您在http://发布的代码stackoverflow.com/questions/6111248/iterate-twice-on-values也输出相同的重复值。它似乎lit.previous()只适用于on.time.ie如果有10个元素,如果lit.previous完成,指针只能到第9个元素而不是第1个元素 –

回答

1

我找到了答案。 如果我们试图在减速迭代两倍以下

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 
+1

+1是的,它会工作,但它不使用迭代器。 – anubhava

+0

@anubhava:是的,它没有使用迭代器,在这里我们做了一个相同的副本。当巨大的数据来临时,它可能不是很好的存储重复。但你的答案很好。没有创建副本只是迭代通过元素。但是对我来说运气不好,它不能正常工作。您是否发现我以前使用迭代器的代码中存在任何错误? –

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); 
    } 
} 
+0

感谢您的回复Mark Vickery.But我无法遍历值两次 public void reduce(Text key,Iterable values,Context context) –

+1

如果这解决了你的问题,请看看:http://stackoverflow.com/questions/6111248/iterate-twice-on-values –

+0

@汤姆塞巴斯蒂安:是的,我看着,但w但我申请了代码。在第一次传球中,我能够正确地获得所有值,在那里我能够获得最小值和最大值。但是对于第二次传球,我需要遍历每个值。但是我只能获得第一个元素(重复)。无法在第二遍中获取所有值。 –