2017-02-22 23 views
2

у меня есть кадр данных искрой, которая выглядит следующим образом:Как разделить одну строку в несколько строк в Java Спарк

id var_a var_b 
-- ----- ----- 
01 1  2 
02 3  0 

, и я хочу, чтобы разделить значения в несколько строк, как это

id var_name var_value 
-- -------- --------- 
01 var_a 1 
01 var_b 2 
02 var_a 3 
02 var_b 0 

Каков наилучший способ сделать это с помощью Java Spark 1.6 API?

+0

Have также посмотреть на [шарниром] (https://spark.apache.org/docs/1.6.0/api/java/org/apache/ spark/sql/GroupedData.html # pivot (java.lang.String)). – pheeleeppoo

ответ

1

Новый FlatMapFunction сделал работу:

import java.util.ArrayList; 
import java.util.List; 

import org.apache.commons.lang3.ArrayUtils; 
import org.apache.spark.sql.Row; 
import org.apache.spark.sql.RowFactory; 

/** 
* id var_a var_b 
* -- ----- ----- 
* 01 1  2 
* 02 3  0 
* 
* becomes 
* 
* id var_name var_value 
* -- -------- --------- 
* 01 var_a 1 
* 01 var_b 2 
* 02 var_a 3 
* 02 var_b 0 
* 
*/ 
public class OneToManyMapFunction implements FlatMapFunction<Row, Row> { 

    //indexes of fields that won't change in the new rows (id) 
    private int[] fixedFields = {0}; 
    //indexes of fields that will create new rows (var_a, var_b) 
    private int[] dynamicFields = {1, 2}; 
    //names of the dynamic fields 
    private String[] dynamicFieldsName = {"var_a", "var_b"}; 

    public OneToManyMapFunction() {} 

    @Override 
    public Iterable<Row> call(Row row) throws Exception { 

     List<Row> rows = new ArrayList<Row>(); 
     Object[] fixedValues = ArrayUtils.EMPTY_OBJECT_ARRAY; 

     //add values that won't change in the new rows 
     for (int i = 0; i < fixedFields.length; i++) { 
      fixedValues = ArrayUtils.add(fixedValues, row.get(fixedFields[i])); 
     } 

     //create new rows 
     for (int i = 0; i < dynamicFields.length; i++) { 
      //copy fixed values (id) 
      Object[] values = ArrayUtils.clone(fixedValues); 

      //add dynamic value name (var_a or var_b) 
      values = ArrayUtils.add(values, dynamicFieldsName[i]); 
      //add dynamic value 
      values = ArrayUtils.add(values, row.get(dynamicFields[i])); 

      //create new row for dynamic val 
      Row newRow = RowFactory.create(values); 
      rows.add(newRow); 
     } 

     return rows; 
    } 

} 
1

flatMap - это функция, которую вы ищете.

Он позволяет сгенерировать несколько записей из одного.

+0

Хорошо, но какая функция правильная, что делает отображение? новая функция >()? – koopa

+0

Посмотрите на подпись 'flatMap': https://spark.apache.org/docs/1.6.0/api/java/org/apache/spark/api/java/JavaRDDLike.html#flatMap(org.apache. spark.api.java.function.FlatMapFunction) Он хочет «FlatMapFunction»: https://spark.apache.org/docs/1.6.0/api/java/org/apache/spark/api/java/function/ FlatMapFunction.html Итак, вам нужна новая функция > ' –