Scala 来自不同数据帧的火花和列

Scala 来自不同数据帧的火花和列,scala,apache-spark,dataframe,apache-spark-sql,Scala,Apache Spark,Dataframe,Apache Spark Sql,我们有两个数据帧(注意Scala语法用于说明) valdf1=sc.parallelize(1到4).map(i=>(i,i*10)).toDF(“id”,“x”) val df2=sc.parallelize(2到4).map(i=>(i,i*100)).toDF(“id”,“y”) 如何从每个帧中求和一列,从而获得这个新的数据帧 +---+---------+ |id | x_+y| +---+---------+ | 1| 10| | 2| 220| | 3|

我们有两个数据帧(注意Scala语法用于说明)

valdf1=sc.parallelize(1到4).map(i=>(i,i*10)).toDF(“id”,“x”)
val df2=sc.parallelize(2到4).map(i=>(i,i*100)).toDF(“id”,“y”)
如何从每个帧中求和一列,从而获得这个新的数据帧

+---+---------+
|id | x_+y|
+---+---------+
|  1|       10|
|  2|      220|
|  3|      330|
|  4|      440|
+---+---------+
注意 尝试了这个,但它使第一行无效

sqlContext.sql(“选择df1.id,x+y作为x_+y,从df1左侧连接df1.id=df2.id上的df2”).show
+---+--------+
|id | x_+y|
+---+--------+
|1 |空|
|  2|     220|
|  3|     330|
|  4|     440|
+---+--------+

这在Python中有效。

在Scala中注意到了这个解决方案

val d = sqlContext.sql("""
  select df1.id, x, y from df1 left join df2 on df1.id=df2.id""").na.fill(0)
要连接帧并将不可用的值替换为零,然后定义此UDF

import org.apache.spark.sql.functions
import org.apache.spark.sql.functions._

val plus: (Int,Int) => Int = (x:Int,y:Int) => x+y
val plus_udf = udf(plus)

d.withColumn("x_plus_y", plus_udf($"x", $"y")).show
+---+---+---+--------+
| id|  x|  y|x_plus_y|
+---+---+---+--------+
|  1| 10|  0|      10|
|  2| 20|200|     220|
|  3| 30|300|     330|
|  4| 40|400|     440|
+---+---+---+--------+

您甚至不需要为此使用自定义项:

val df3 = df1.as('a).join(df2.as('b), $"a.id" === $"b.id","left").
               select(df1("id"),'x,'y,(coalesce('x, lit(0)) + coalesce('y, lit(0))).alias("x_plus_y")).na.fill(0)

df3.show
// df3: org.apache.spark.sql.DataFrame = [id: int, x: int, y: int, x_plus_y: int]
// +---+---+---+--------+
// | id|  x|  y|x_plus_y|
// +---+---+---+--------+
// |  1| 10|  0|      10|
// |  2| 20|200|     220|
// |  3| 30|300|     330|
// |  4| 40|400|     440|
// +---+---+---+--------+

如果
x
y
列的值为空怎么办?
val df3 = df1.as('a).join(df2.as('b), $"a.id" === $"b.id","left").
               select(df1("id"),'x,'y,(coalesce('x, lit(0)) + coalesce('y, lit(0))).alias("x_plus_y")).na.fill(0)

df3.show
// df3: org.apache.spark.sql.DataFrame = [id: int, x: int, y: int, x_plus_y: int]
// +---+---+---+--------+
// | id|  x|  y|x_plus_y|
// +---+---+---+--------+
// |  1| 10|  0|      10|
// |  2| 20|200|     220|
// |  3| 30|300|     330|
// |  4| 40|400|     440|
// +---+---+---+--------+