Настройка TwoDArrayWritable в Hadoop и невозможность повторить то же самое в редюсере

Попытка передать 2 двумерных массива в качестве значения из картографа. В Hadoop у нас есть TwoDArrayWritable, который принимает от 1 до 2D array в качестве входных данных. Чтобы выполнить мой вариант использования, я попытался отредактировать TwoDArrayWritable, чтобы ввести данные 2 - 2D array.

/**
 * A Writable for 2D arrays containing a matrix of instances of a class.
 */
public class MyTwoDArrayWritable implements Writable {


    private Class valueClass;
    private Writable[][] values;


    private Class valueClass1;
    private Writable[][] values1;


    public MyTwoDArrayWritable(Class valueClass,Class valueClass1) {
        this.valueClass = valueClass;
        this.valueClass1 = valueClass1;
    }

    public MyTwoDArrayWritable(Class valueClass, DoubleWritable[][] values,Class valueClass1, DoubleWritable[][] values1) {
        this(valueClass, valueClass1);
        this.values = values;
        this.values1 = values1;
    }

    public Object toArray() {
        int dimensions[] = {values.length, 0};
        Object result = Array.newInstance(valueClass, dimensions);
        for (int i = 0; i < values.length; i++) {
            Object resultRow = Array.newInstance(valueClass, values[i].length);
            Array.set(result, i, resultRow);
            for (int j = 0; j < values[i].length; j++) {
                Array.set(resultRow, j, values[i][j]);
            }
        }
        return result;
    }



    /**
     * @return the valueClass
     */
    public Class getValueClass() {
        return valueClass;
    }

    /**
     * @param valueClass the valueClass to set
     */
    public void setValueClass(Class valueClass) {
        this.valueClass = valueClass;
    }

    /**
     * @return the values
     */
    public Writable[][] getValues() {
        return values;
    }

    /**
     * @param values the values to set
     */
    public void setValues(DoubleWritable[][] values,DoubleWritable[][] values1) {
        this.values = values;
        this.values = values1;
    }

    /**
     * @return the valueClass1
     */
    public Class getValueClass1() {
        return valueClass1;
    }

    /**
     * @param valueClass1 the valueClass1 to set
     */
    public void setValueClass1(Class valueClass1) {
        this.valueClass1 = valueClass1;
    }

    /**
     * @return the values1
     */
    public Writable[][] getValues1() {
        return values1;
    }


    public void readFields(DataInput in) throws IOException {
        // construct matrix
        values = new Writable[in.readInt()][];
        for (int i = 0; i < values.length; i++) {
            values[i] = new Writable[in.readInt()];
        }

        // construct values
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values[i].length; j++) {
                Writable value;                             // construct value
                try {
                    value = (Writable) valueClass.newInstance();
                } catch (InstantiationException e) {
                    throw new RuntimeException(e.toString());
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e.toString());
                }
                value.readFields(in);                       // read a value
                values[i][j] = value;                       // store it in values
            }
        }
    }

    public void write(DataOutput out) throws IOException {
        out.writeInt(values.length);                 // write values
        for (int i = 0; i < values.length; i++) {
            out.writeInt(values[i].length);
        }
        for (int i = 0; i < values.length; i++) {
            for (int j = 0; j < values[i].length; j++) {
                values[i][j].write(out);
            }
        }
    }


}

И выпустил 2 2D двойных массива из маппера.

MyTwoDArrayWritable array = new MyTwoDArrayWritable (DoubleWritable.class,DoubleWritable.class);
DoubleWritable[][] myInnerArray = new DoubleWritable[EtransEkey.length][EtransEkey[0].length];
DoubleWritable[][] myInnerArray1 = new DoubleWritable[EtransDevalue.length][EtransDevalue[0].length];
// set values in myInnerArray
for (int k1 = 0; k1 < EtransEkey.length; k1++) {
 for(int j1=0;j1< EtransEkey[0].length;j1++){
     myInnerArray[k1][j1] = new DoubleWritable(EtransEkey[k1][j1]);

 }
}

for (int k1 = 0; k1 < EtransDevalue.length; k1++) {
 for(int j1=0;j1< EtransDevalue[0].length;j1++){
     myInnerArray1[k1][j1] = new DoubleWritable(EtransDevalue[k1][j1]);
 }
}

array.set(myInnerArray,myInnerArray1); 

Отображается ошибка в array.set(myInnerArray,myInnerArray1);

/*
 * The method set(DoubleWritable[][], DoubleWritable[][]) is undefined for the type MyTwoDArrayWritableritable
 */

EDIT: Как перебрать эти значения в Reducer, чтобы получить матрицу myInnerArray и матрицу myInnerArray1?

До сих пор то, что я сделал, это

for (MyTwoDArrayWritable c : values) {
            System.out.println(c.getValues());
            DoubleWritable[][] myInnerArray = new DoubleWritable[KdimRow][KdimCol];
            for (int k1 = 0; k1 < KdimRow; k1++) {
                 for(int j1=0;j1< KdimCol;j1++){
                     myInnerArray[k1][j1] = new DoubleWritable();

                 }
        }

Но как сохранить их обратно в двойной массив?


person USB    schedule 23.07.2014    source источник


Ответы (1)


Вы не определили метод set в MyTwoDArrayWritable, поэтому отображается эта ошибка. Вместо вызова array.set вы должны использовать уже определенный вами метод, который делает именно то, что вам нужно: setValues, поэтому замените

array.set(myInnerArray,myInnerArray1); 

с

array.setValues(myInnerArray,myInnerArray1); 
person Balduz    schedule 23.07.2014
comment
о правильно, я вызывал неправильный метод. Как пройти через этот MyTwoDArrayWritable в Reducer, чтобы получить myInnerArray и myInnerArray1 - person USB; 23.07.2014
comment
Вы сказали, что используете MyTwoDArrayWritable в качестве значений, верно? Таким образом, для каждого ключа в редукторе у вас должна быть коллекция MyTwoDArrayWritable. Переберите их и постройте матрицу так же, как вы делаете в опубликованном вами коде. - person Balduz; 23.07.2014
comment
да, мои значения MyTwoDArrayWritable. Но как вернуть их к двойному массиву? Я застрял. Пожалуйста, посмотрите мое редактирование - person USB; 23.07.2014
comment
Мой ответ решает вашу первоначальную проблему, и вы создали еще одну ветку для решения второй проблемы. Не могли бы вы принять ответ? - person Balduz; 24.07.2014