在apache spark中,如何在groupBy()之后将一列mllib Vector收集到一个列表中?

时间:2017-01-11 17:34:52

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

我正在使用Spark和Java 8.我有一个数据框,其中一列包含一个mllib.linalg.Vector。我想分组数据框中的其他列之一,比如ID列,并将特征向量“collect_list”放入列表中。我收到以下错误。我不明白为什么。这是一个通用操作,为什么它关心列中数据的类型?它适用于标量数字或字符串等,但似​​乎不适用于mllib Vector。这是否有解决方法?可能是collect_list()以外的其他函数?

No handler for Hive udf class org.apache.hadoop.hive.ql.udf.generic.GenericUDAFCollectList because: org.apache.spark.mllib.linalg.VectorUDT@f71b0bce (of class org.apache.spark.mllib.linalg.VectorUDT)

1 个答案:

答案 0 :(得分:1)

您使用的Spark版本是什么?使用Spark 1.6.2,它会引发您提到的相同错误,但这与Spark 2.0.1一起运行正常。请参阅下面的示例代码和输出。

public class JavaVectorExample {
    public static void main(String[] args) {
    //SparkSession
    SparkSession spark = SparkSession
      .builder()
      .appName("JavaVectorExample")
      .master("local[2]")
      .getOrCreate();
    //schema
    StructType schema = createStructType(new StructField[]{
      createStructField("id", IntegerType, false),
      createStructField("label", DoubleType, false),
      createStructField("features", new VectorUDT(), false),
    });
    //dataset
    Row row1 = RowFactory.create(0, 1.0, Vectors.dense(0.0, 10.0, 0.5));
    Row row2 = RowFactory.create(1, 1.0, Vectors.dense(1.0, 10.5, 0.5));
    Row row3 = RowFactory.create(0, 1.5, Vectors.dense(0.0, 10.5, 1.0));
    Dataset<Row> dataset = spark.createDataFrame(Arrays.asList(row1,row2,row3), schema);
    dataset.printSchema();
    //groupby
    dataset.groupBy(col("id")).agg(collect_list(col("features"))).show(false);
    spark.stop();
  }
}

这是输出。

+---+--------------------------------+
|id |collect_list(features)          |
+---+--------------------------------+
|1  |[[1.0,10.5,0.5]]                |
|0  |[[0.0,10.0,0.5], [0.0,10.5,1.0]]|
+---+--------------------------------+