如何从变量值向数据框添加列?
我知道我可以使用.toDF(colName)
创建数据框,.withColumn
是添加列的方法。但是,当我尝试以下操作时,出现类型不匹配错误:
val myList = List(1,2,3)
val myArray = Array(1,2,3)
myList.toDF("myList")
.withColumn("myArray", myArray)
类型不匹配,预期:列,实际:数组[Int]
此编译错误在myArray
调用中的.withColumn
上。如何将它从Array [Int]转换为Column类型?
答案 0 :(得分:1)
错误消息具有正确的内容,您需要输入一个列(或lit()
)作为第二个参数withColumn()
试试这个
import org.apache.spark.sql.functions.typedLit
val myList = List(1,2,3)
val myArray = Array(1,2,3)
myList.toDF("myList")
.withColumn("myArray", typedLit(myArray))
:)
答案 1 :(得分:0)
不确定withColumn
是你真正想要的。您可以应用lit()
使myArray符合方法规范,但结果将是DataFrame中每一行的相同数组值:
myList.toDF("myList").withColumn("myArray", lit(myArray)).
show
// +------+---------+
// |myList| myArray|
// +------+---------+
// | 1|[1, 2, 3]|
// | 2|[1, 2, 3]|
// | 3|[1, 2, 3]|
// +------+---------+
如果您尝试按列方式合并两个集合,则它与withColumn
提供的变换不同。在这种情况下,您需要将每个转换为DataFrame并通过join
进行组合。
现在,如果两个集合的元素是行标识并且在示例中彼此成对匹配,并且您希望以这种方式连接它们,则可以简单地加入转换后的DataFrame:
myList.toDF("myList").join(
myArray.toSeq.toDF("myArray"), $"myList" === $"myArray"
).show
// +------+-------+
// |myList|myArray|
// +------+-------+
// | 1| 1|
// | 2| 2|
// | 3| 3|
// +------+-------+
但是如果两个集合具有不可连接的元素并且您只想按列合并它们,则需要使用两个数据帧中的兼容行标识列来连接它们。如果没有这样的行标识列,一种方法是创建自己的rowId
,如下例所示:
import org.apache.spark.sql.Row
import org.apache.spark.sql.types._
val df1 = List("a", "b", "c").toDF("myList")
val df2 = Array("x", "y", "z").toSeq.toDF("myArray")
val rdd1 = df1.rdd.zipWithIndex.map{
case (row: Row, id: Long) => Row.fromSeq(row.toSeq :+ id)
}
val df1withId = spark.createDataFrame( rdd1,
StructType(df1.schema.fields :+ StructField("rowId", LongType, false))
)
val rdd2 = df2.rdd.zipWithIndex.map{
case (row: Row, id: Long) => Row.fromSeq(row.toSeq :+ id)
}
val df2withId = spark.createDataFrame( rdd2,
StructType(df2.schema.fields :+ StructField("rowId", LongType, false))
)
df1withId.join(df2withId, Seq("rowId")).show
// +-----+------+-------+
// |rowId|myList|myArray|
// +-----+------+-------+
// | 0| a| x|
// | 1| b| y|
// | 2| c| z|
// +-----+------+-------+