2016-03-30 28 views
7

Tôi có một tập dữ liệu nhỏ sẽ là kết quả của một công việc Spark. Tôi đang suy nghĩ về việc chuyển đổi tập dữ liệu này thành một khung dữ liệu để thuận tiện khi kết thúc công việc, nhưng đã phải vật lộn để xác định chính xác lược đồ. Vấn đề là trường cuối cùng bên dưới (topValues); nó là một ArrayBuffer của tuples - keys và count.Spark: Lập trình tạo lược đồ dataframe theo cách có lập trình trong scala

val innerSchema = 
    StructType(
     Array(
     StructField("value", StringType), 
     StructField("count", LongType) 
    ) 
    ) 
    val outputSchema = 
    StructType(
     Array(
     StructField("name", StringType, nullable=false), 
     StructField("index", IntegerType, nullable=false), 
     StructField("count", LongType, nullable=false), 
     StructField("empties", LongType, nullable=false), 
     StructField("nulls", LongType, nullable=false), 
     StructField("uniqueValues", LongType, nullable=false), 
     StructField("mean", DoubleType), 
     StructField("min", DoubleType), 
     StructField("max", DoubleType), 
     StructField("topValues", innerSchema) 
    ) 
    ) 

    val result = stats.columnStats.map{ c => 
    Row(c._2.name, c._1, c._2.count, c._2.empties, c._2.nulls, c._2.uniqueValues, c._2.mean, c._2.min, c._2.max, c._2.topValues.topN) 
    } 

    val rdd = sc.parallelize(result.toSeq) 

    val outputDf = sqlContext.createDataFrame(rdd, outputSchema) 

    outputDf.show() 

Các lỗi tôi nhận được là một MatchError: scala.MatchError: ArrayBuffer((10,2), (20,3), (8,1)) (of class scala.collection.mutable.ArrayBuffer)

Khi tôi gỡ lỗi và kiểm tra đối tượng của tôi, tôi thấy điều này:

rdd: ParallelCollectionRDD[2] 
rdd.data: "ArrayBuffer" size = 2 
rdd.data(0): [age,2,6,0,0,3,14.666666666666666,8.0,20.0,ArrayBuffer((10,2), (20,3), (8,1))] 
rdd.data(1): [gender,3,6,0,0,2,0.0,0.0,0.0,ArrayBuffer((M,4), (F,2))] 

Dường như với tôi rằng tôi đã mô tả chính xác ArrayBuffer của các bộ dữ liệu trong innerSchema của tôi, nhưng Spark không đồng ý.

Bất kỳ ý tưởng nào tôi nên xác định giản đồ?

+0

Sẽ hữu ích nếu bạn cung cấp dữ liệu mẫu hoặc ít nhất là loại chính xác của 'rdd'. – zero323

Trả lời

10
val rdd = sc.parallelize(Array(Row(ArrayBuffer(1,2,3,4)))) 
val df = sqlContext.createDataFrame(
    rdd, 
    StructType(Seq(StructField("arr", ArrayType(IntegerType, false), false) 
) 

df.printSchema 
root 
|-- arr: array (nullable = false) 
| |-- element: integer (containsNull = false) 

df.show 
+------------+ 
|   arr| 
+------------+ 
|[1, 2, 3, 4]| 
+------------+ 
+0

Có, ArrayType là cách tiếp cận đúng. Cảm ơn! Lược đồ cuối cùng của tôi là trong câu trả lời của tôi. – Stuart

4

Như David đã chỉ ra, tôi cần sử dụng ArrayType. Spark hài lòng với điều này:

val outputSchema = 
    StructType(
     Array(
     StructField("name", StringType, nullable=false), 
     StructField("index", IntegerType, nullable=false), 
     StructField("count", LongType, nullable=false), 
     StructField("empties", LongType, nullable=false), 
     StructField("nulls", LongType, nullable=false), 
     StructField("uniqueValues", LongType, nullable=false), 
     StructField("mean", DoubleType), 
     StructField("min", DoubleType), 
     StructField("max", DoubleType), 
     StructField("topValues", ArrayType(StructType(Array(
      StructField("value", StringType), 
      StructField("count", LongType) 
     )))) 
    ) 
    ) 
Các vấn đề liên quan