如何从Integer RDD创建spark数据帧

时间:2016-03-28 07:34:48

标签: apache-spark dataframe apache-spark-sql rdd

如何从DataFrame包含整数创建JavaRDD。我做过类似下面的事但没有工作。

List<Integer> input = Arrays.asList(101, 103, 105);
JavaRDD<Integer> inputRDD = sc.parallelize(input);
DataFrame dataframe = sqlcontext.createDataFrame(inputRDD, Integer.class);

ClassCastExceptionorg.apache.spark.sql.types.IntegerType$ cannot be cast to org.apache.spark.sql.types.StructType

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

显然(虽然不直观),此createDataFrame重载只能用于“Bean”类型,这意味着不对应于任何内置Spark SQL类型的类型

您可以看到,在源代码中,您传递的类与JavaTypeInference.inferDataType中的Spark SQL类型匹配,结果将转换为StructType(请参阅dataType.asInstanceOf[StructType] in SQLContext.getSchema - 但内置的“原始”类型(如IntegerType)是 NOT StructType ...看起来像是一个错误或无证件的行为。 ...

<强> WORKAROUNDS

  1. 用“bean”类包裹你的Integer(我知道这很难看):

    public static class MyBean {
        final int value;
    
        MyBean(int value) {
            this.value = value;
        }
    
        public int getValue() {
            return value;
        }
    }
    
    List<MyBean> input = Arrays.asList(new MyBean(101), new MyBean(103), new MyBean(105));
    JavaRDD<MyBean> inputRDD = sc.parallelize(input);
    DataFrame dataframe = sqlcontext.createDataFrame(inputRDD, MyBean.class);
    
    dataframe.show(); // this works...
    
  2. 自己转换为RDD<Row>

    // convert to Rows:
    JavaRDD<Row> rowRdd = inputRDD.map(new Function<Integer, Row>() {
        @Override
        public Row call(Integer v1) throws Exception {
            return RowFactory.create(v1);
        }
    });
    
    // create schema (this looks nicer in Scala...):
    StructType schema = new StructType(new StructField[]{new StructField("number", IntegerType$.MODULE$, false, Metadata.empty())});
    
    DataFrame dataframe = sqlcontext.createDataFrame(rowRdd, schema);
    dataframe.show(); // this works...
    

答案 1 :(得分:0)

现在,在Spark 2.2中,您可以执行以下操作来创建数据集。

Dataset<Integer> dataSet = sqlContext().createDataset(javardd.rdd(), Encoders.INT());