假如我们要通过RDD[Row]创建一个包含多个列的DataFrame,重点是列的数据类型可能会包含多个,这时候需要有一点技巧。
| uid | user_name | age | income |
|:----|:----------|:----|:-------|
| 1111 | nituchao | 21 | 123.0 |
这个`DataFrame`里包含多个数据类型:
* uid: Long
* user_name: String
* age: Int
* income: Double
我们可以使用下面的方式来构建:
```scala
import org.apache.spark.sql.Row
import org.apache.spark.sql.types.{DoubleType, IntegerType, LongType, StringType, StructField, StructType}
val uidSeq = Seq(1111L)
val nameSeq = Seq("nituchao")
val ageSeq = Seq(21)
val incomeSeq = Seq(123.0)
val rowRDD = spark.sparkContext.parallelize(Seq(Row.fromSeq(uidSeq ++ userNameSeq ++ ageSeq ++ incomeSeq)))
val schema = StructType(Seq(StructField("uid", LongType, nullable = true),
StructField("name", StringType, nullable = true),
StructField("age", IntegerType, nullable = true),
StructField("sex", DoubleType, nullable = true)))
val df = spark.sqlContext.createDataFrame(rowRDD, schema)
df.printSchema()
df.show()
```
输出:
```shell
root
|-- uid: long (nullable = true)
|-- name: string (nullable = true)
|-- age: integer (nullable = true)
|-- sex: double (nullable = true)
+----+---------+---+-----+
| uid|name |age| sex|
+----+---------+---+-----+
|1111| nituchao| 21|123.0|
+----+---------+---+-----+
```
上面的技巧在于,使用`Row.fromSeq()`时,不同类型的数据,要用`Seq()`分别包起来然后`++`拼接后传进去。因为Seq中的元素必须是同类型的,如直接构造成一个Seq则会自动进行类型转换,多种类型数据不能混用。
问题不大,却造成很大困扰。