Apache spark 如何将RDD[List[Int]]转换为数据帧?

Apache spark 如何将RDD[List[Int]]转换为数据帧?,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我有一个RDD[List[Int]],我不知道List[Int]的计数,我想把我RDD[List[Int]转换成DataFrame,我该怎么办 这是我的意见: val l1=Array(1,2,3,4) val l2=Array(1,2,3,4) val Lz=Seq(l1,l2) val rdd1=sc.parallelize(Lz,2) 这是我的预期结果: +---+---+---+---+ | _1| _2| _3| _4| +---+---+---+-

我有一个
RDD[List[Int]]
,我不知道
List[Int]
的计数,我想把我
RDD[List[Int]
转换成
DataFrame
,我该怎么办

这是我的意见:

    val l1=Array(1,2,3,4)
    val l2=Array(1,2,3,4)
    val Lz=Seq(l1,l2)
    val rdd1=sc.parallelize(Lz,2) 
这是我的预期结果:

+---+---+---+---+
| _1| _2| _3| _4|
+---+---+---+---+
|  1|  2|  3|  4|
|  1|  2|  3|  4|
+---+---+---+---+

您可以执行以下操作:

val l1=Array(1,2,3,4)
val l2=Array(1,2,3,4)
val Lz=Seq(l1,l2)
val df = sc.parallelize(Lz,2).map{
    case Array(val1, val2, val3, val4) => (val1, val2, val3, val4)
}.toDF

df.show
// +---+---+---+---+
// | _1| _2| _3| _4|
// +---+---+---+---+
// |  1|  2|  3|  4|
// |  1|  2|  3|  4|
// +---+---+---+---+
val sch = df.schema // I just took the schema from the old df but you can add one programmatically 

val df2 = spark.createDataFrame(sc.parallelize(Lz,2).map{ Row.fromSeq(_) }, sch)

df2.show
// +---+---+---+---+
// | _1| _2| _3| _4|
// +---+---+---+---+
// |  1|  2|  3|  4|
// |  1|  2|  3|  4|
// +---+---+---+---+
如果有很多列,则需要以不同的方式进行操作,但需要了解数据的架构,否则将无法执行以下操作:

val l1=Array(1,2,3,4)
val l2=Array(1,2,3,4)
val Lz=Seq(l1,l2)
val df = sc.parallelize(Lz,2).map{
    case Array(val1, val2, val3, val4) => (val1, val2, val3, val4)
}.toDF

df.show
// +---+---+---+---+
// | _1| _2| _3| _4|
// +---+---+---+---+
// |  1|  2|  3|  4|
// |  1|  2|  3|  4|
// +---+---+---+---+
val sch = df.schema // I just took the schema from the old df but you can add one programmatically 

val df2 = spark.createDataFrame(sc.parallelize(Lz,2).map{ Row.fromSeq(_) }, sch)

df2.show
// +---+---+---+---+
// | _1| _2| _3| _4|
// +---+---+---+---+
// |  1|  2|  3|  4|
// |  1|  2|  3|  4|
// +---+---+---+---+
除非提供架构,否则除了有一个数组列之外,您将无法做很多事情:

val df3 = sc.parallelize(Lz,2).toDF
// df3: org.apache.spark.sql.DataFrame = [value: array<int>]
df3.show
// +------------+
// |       value|
// +------------+
// |[1, 2, 3, 4]|
// |[1, 2, 3, 4]|
// +------------+
df3.printSchema
//root
// |-- value: array (nullable = true)
// |    |-- element: integer (containsNull = false)
val df3=sc.parallelize(Lz,2).toDF
//df3:org.apache.spark.sql.DataFrame=[value:array]
df3.show
// +------------+
//|价值|
// +------------+
// |[1, 2, 3, 4]|
// |[1, 2, 3, 4]|
// +------------+
df3.printSchema
//根
//|--值:数组(nullable=true)
//| |--元素:整数(containsnall=false)

也许有其他更好的功能方法可以做到这一点,但这也很有效:

def getSchema(myArray : Array[Int]): StructType = {
    var schemaArray = scala.collection.mutable.ArrayBuffer[StructField]()
    for((el,idx) <- myArray.view.zipWithIndex){
        schemaArray += StructField("col"+idx , IntegerType, true)
    }
    StructType(schemaArray)
}

val l1=Array(1,2,3,4)
val l2=Array(1,2,3,4)
val Lz=Seq(l1,l2)
val rdd1=sc.parallelize(Lz,2).map(Row.fromSeq(_))
val schema = getSchema(l1) //Since both arrays will be of same type and size
val df = sqlContext.createDataFrame(rdd1, schema)
df.show()

+----+----+----+----+
|col0|col1|col2|col3|
+----+----+----+----+
|   1|   2|   3|   4|
|   1|   2|   3|   4|
+----+----+----+----+
def getSchema(myArray:Array[Int]):StructType={
var schemaArray=scala.collection.mutable.ArrayBuffer[StructField]()

对于((el,idx)你不知道
l1
l2
的计数,但是它们总是相同长度的吗?l1和l2的计数是相同的,但是list[Int]的计数不一定是相同长度的。我不知道list[Int]的计数,所以我无法得到模式l1和l2的计数是相同的,但是list[Int]的计数是相同的不一定是相同的长度。你不能这样做。除非你提供一个模式,否则你只会有一个entries数组。我有一个数组[String],数组和列表的计数是相同的,数组的值是列名,我可以这样做吗?@mentongwu我已经给出了所有可能的方法,其他任何事情都是不可能的。