将Spark Dataframe写入JSON会丢失MLLIB Sparse Vector的格式

时间:2016-06-15 15:26:36

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

我正在给json写一个(Java)Spark Dataframe。其中一列是mllib稀疏向量。后来我将json文件读入第二个Dataframe,但稀疏矢量列现在是WrappedArray,并且在第二个数据帧中不被读取为稀疏矢量。我的问题:为了得到一个稀疏的矢量列而不是一个wrappedArray列,我可以在写入方面或读取方面做些什么吗?

写作:

initialDF.coalesce(1).write().json("initial_dataframe");

读:

DataFrame secondDF = hiveContext.read().json("initial_dataframe");

1 个答案:

答案 0 :(得分:3)

答案很简单。提供DataFrameReader

的架构
import org.apache.spark.mllib.linalg.VectorUDT

val path: String = ???
val df = Seq((1L, Vectors.parse("(5, [1.0, 3.0], [2.0, 3.0])"))).toDF
df.write.json(path)

spark.read.json(path).printSchema
// root
//  |-- _1: long (nullable = true)
//  |-- _2: struct (nullable = true)
//  |    |-- indices: array (nullable = true)
//  |    |    |-- element: long (containsNull = true)
//  |    |-- size: long (nullable = true)
//  |    |-- type: long (nullable = true)
//  |    |-- values: array (nullable = true)
//  |    |    |-- element: double (containsNull = true)

提供正确的架构时

import org.apache.spark.mllib.linalg.VectorUDT
import org.apache.spark.sql.types.{LongType, StructField, StructType}

val schema = StructType(Seq(
  StructField("_1", LongType, true),
  StructField("_2", new VectorUDT, true)))

spark.read.schema(schema).json(path).printSchema
root
 |-- _1: long (nullable = true)
 |-- _2: vector (nullable = true)

spark.read.schema(schema).json(path).show(1)
// +---+-------------------+
// | _1|                 _2|
// +---+-------------------+
// |  1|(5,[1,3],[2.0,3.0])|
// +---+-------------------+

通常,如果您使用的是不提供架构发现机制的源providing schema explicitly is a good idea

如果JSON不是硬性要求,Parquet将保留矢量类型并提供模式发现机制。