在使用sparkSQL,有时想要把rdd中的数据转换成DataFrame,RDD中的的数据可能时Array类型,或者是想要把数组类型中的所有元素放到Row中,当数组中的元素特别多时,可能就会变得更加麻烦,其实Row的Object中为我们提供了一个很好的方法,就是merge方法,话不多说,直接看代码吧
Object Demo {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName(s"${this.getClass.getName}").setMaster("local")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
//这里我是并行化创建了一个RDD,当然也可从文件读取
val lines:RDD[String] = sc.parallelize(Array("a 1 c","n 2 m"))
//把每一行数据都按空格进行切分后,得到的RDD中的是Array数组
val splits: RDD[Array[String]] = lines.map(_.split(" "))
//现在想要把splits转换成RDD[Row]类型,以进行转换为DataFrame
val rowRDD: RDD[Row] = .map(t => {
var row: Row = Row() //先创建一个Row,空的
for (i <- 0 until (t.size)) {
//每次把这次的Row类型,和原来的Row进行合并, 最后的row中有是
//数组里面的所有字段
//把第2个值 转成 int类型 在添加到Row中
if(i==1)row = Row.merge(row,Row(t(i).toInt))
else row = Row.merge(row,Row(t(i)))
}
//最后把row 返回,此时的row中相当于Row(t(0),t(1).toInt,t(2))
//在数字段数特别多时,就会特别麻烦,可以使用上面的那种方法
row
})
//最后在创建元数据
val structType = StructType(List(StructField("name",StringType,true),StructField("name1",IntegerType,true),StructField("name2",StringType,true)))
val df1 = sqlContext.createDataFrame(rowRDD,structType)
df1.show()
sc.stop()
}
}
上面的列子字段比较少,可能不是特别明显,可以通过下面的列子在进行比较
object Bz2toParquet01 {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName(s"${this.getClass.getName}").setMaster("local").set("spark.serializer","org.apache.spark.serializer.KryoSerializer")
val sc = new