Case class scala-dataset-如何在两个case类上使用函数?
我有两个数据集,并创建了两个case类(我之所以不将ds连接在一起,是因为我想返回ds B中的第一个匹配记录以及ds A中的键) 以下是我迄今为止的尝试。如何将该函数映射到两个case类?非常感谢!我是新来的Case class scala-dataset-如何在两个case类上使用函数?,case-class,Case Class,我有两个数据集,并创建了两个case类(我之所以不将ds连接在一起,是因为我想返回ds B中的第一个匹配记录以及ds A中的键) 以下是我迄今为止的尝试。如何将该函数映射到两个case类?非常感谢!我是新来的 case class a_class (idA: Int, numA: Int) case class b_class(idB: Int, numB:Int ) def findNum(a:a_Class, b:b_class): Int = { if (a.idA =!=b.i
case class a_class (idA: Int, numA: Int)
case class b_class(idB: Int, numB:Int )
def findNum(a:a_Class, b:b_class): Int = {
if (a.idA =!=b.idB){
break
}else{
return b.numB
}
}
aTb.createOrReplaceTempView("tableA")
bTb.createOrReplaceTempView("tableB")
var aDS = sqlContext.table("tableA").as[a_class]
var bDS = sqlContext.table("pview").as[b_class]
//a_class.map(, => )).show //how do I use findNum function here?
输入示例:
+------+---+
|idA |numA|
+------+---+
| a |100|
| b |200|
+------+---+
+------+---+
|idB |numB|
+------+---+
|a |500|
|a |600|
+------+---+
因此,预期输出为500,因为第一行是表B中的第一条匹配记录您的解决方案在于
join
、groupBy
和聚合
首先,您的case类
与示例输入数据不匹配,因为a
和b
不能是int
类型。因此,案例类
应该
case class a_class (idA: String, numA: Int)
case class b_class(idB: String, numB:Int )
使用这些案例类
可以创建数据集
。出于测试目的,我创建如下内容
import sqlContext.implicits._
import org.apache.spark.sql.functions._
val tableA = Seq(
a_class("a", 100),
a_class("b", 200)
).toDS
val tableB = Seq(
b_class("a", 500),
b_class("a", 600)
).toDS
然后,可以使用以下方法获得最终的数据集
tableA.join(tableB, $"idA" === $"idB", "inner") // inner join of two datasets
.drop("idA", "numA") //droping columns of tableB
.groupBy("idB") //grouping data to get the first of each group
.agg(first("numB").as("numB")) //taking the first of each group
.show(false)
应该给你什么
+---+----+
|idB|numB|
+---+----+
|a |600 |
+---+----+
已更新
上面的结果与您想要的输出不匹配,这是因为join
对表B
重新排序
你只需这样做就可以得到你想要的输出
tableB.groupBy("idB")
.agg(first("numB").as("numB"))
.show(false)
结果将是表格B
+---+----+
|idB|numB|
+---+----+
|a |500 |
+---+----+
如果您只需要与tableA
匹配的id
的第一行,那么您将与tableA
合并,如上所述;如果您不需要tableA
的数据,则将作为
val tempTableB = tableB.groupBy("idB")
.agg(first("numB").as("numB"))
tableA.join(tempTableB, $"idA" === $"idB", "inner")
.drop("idA", "numA")
.show(false)
输出是tableB
的第一行与tableA的id
匹配
+---+----+
|idB|numB|
+---+----+
|a |500 |
+---+----+
您可以使用示例输入和预期输出进行更新吗?@user4046073您所说的是什么意思?我之所以不将ds连接在一起,是因为我想返回ds B中的第一条匹配记录以及ds A中的键
。在Spark中,数据帧/数据集
是分布式的。火花中没有第一个或最后一个。@himanshuiitian“火花中没有第一个或最后一个”@JacekLaskowski没错!我的观点是@user4046073想要使用而不加入来执行操作,这是不可能的。谢谢你的回答:)这肯定给了我一些想法。但是预期的输出是“a”,“500”,这是数据集B中的第一个匹配记录。为什么在加入后删除B列?请参阅我更新的答案:)我希望我回答并解决了您的问题。您能否发布另一个问题,提供更详细的信息,如如何创建DetriableB并提供更多错误日志?这样我或其他人就可以帮你了。:)表演是一种行为。既然你还没有在诱惑B中应用动作,那就什么也做不了。操作完成时应用转换。因此,错误似乎消失了,但只要您执行操作,错误就会再次出现。因此,如果你想解决这个问题,要么更新这个问题,要么尽可能详细地询问另一个问题。:)如果没有看到规范和程序,就很难得出结论。:)这就是为什么我要你问另一个问题,并提供详细的信息,以便我们能帮助你理解问题的症结所在