我是 spark 的新手,并在上周问了一个类似的问题。它已编译但无法正常工作。所以我真的不知道该怎么做。这是我的问题:我有一个包含3列的表A,像这样
-----------
A1 A1 A3
-----------
a b c
和另一个表B这样
------------------------------------
B1 B2 B3 B4 B5 B6 B7 B8 B9
------------------------------------
1 a 3 4 5 b 7 8 c
我的逻辑是:A1 A2 A3是我的钥匙,它对应于表B中的B2 B6 B9。我需要建立一个查找功能,将A1 A2 A3作为键并返回给我B8。
这是我上周试过的:
//getting the data in to dataframe
val clsrowRDD = clsfile.map(_.split("\t")).map(p => Row(p(0),p(1),p(2),p(3),p(4),p(5),p(6),p(7),p(8)))
val clsDataFrame = sqlContext.createDataFrame(clsrowRDD, clsschema)
//mapping the three key with the value
val smallRdd = clsDataFrame.rdd.map{row: Row => (mutable.WrappedArray.make[String](Array(row.getString(1), row.getString(5), row.getString(8))), row.getString(7))}
val lookupMap:Map[mutable.WrappedArray[String], String] = smallRdd.collectAsMap()
//build the look up function
def lookup(lookupMap: Map[mutable.WrappedArray[String],String]) =
udf((input: mutable.WrappedArray[String]) => lookupMap.lift(input))
//call the function
val combinedDF = mstrDataFrame.withColumn("ENTP_CLS_CD",lookup(lookupMap)($"SRC_SYS_CD",$"ORG_ID",$"ORG_CD"))
此代码编译,但并没有真正返回我需要的结果。我在想它是因为我传入一个数组作为键,我的表中没有数组。但是当我尝试将地图类型更改为Map[(String,String,String),String]
时,我不知道你如何在函数中传递它。
非常感谢。
答案 0 :(得分:1)
如果您尝试为B8
与A1
和B2
与A2
和B6
与A3
的每个匹配项获得B9
值{1}},然后简单的join
和select
方法就可以了。 创建查找地图会产生复杂性。
正如您所解释的那样,您必须将数据框df1
和df2
设为
+---+---+---+
|A1 |A2 |A3 |
+---+---+---+
|a |b |c |
+---+---+---+
+---+---+---+---+---+---+---+---+---+
|B1 |B2 |B3 |B4 |B5 |B6 |B7 |B8 |B9 |
+---+---+---+---+---+---+---+---+---+
|1 |a |3 |4 |5 |b |7 |8 |c |
|1 |a |3 |4 |5 |b |7 |8 |e |
+---+---+---+---+---+---+---+---+---+
简单join
和select
可以完成
df1.join(df2, $"A1" === $"B2" && $"A2" === $"B6" && $"A3" === $"B9", "inner").select("B8")
应该给你
+---+
|B8 |
+---+
|8 |
+---+
我希望答案很有帮助
<强>更新强>
根据我在您的问题和评论中所理解的内容,您对如何将array
传递到lookup
udf
函数感到困惑。为此,您可以使用array功能。我修改了几乎完美代码的某些部分以使其正常工作
//mapping the three key with the value
val smallRdd = clsDataFrame.rdd
.map{row: Row => (mutable.WrappedArray.make[String](Array(row.getString(1), row.getString(5), row.getString(8))), row.getString(7))}
val lookupMap: collection.Map[mutable.WrappedArray[String], String] = smallRdd.collectAsMap()
//build the look up function
def lookup(lookupMap: collection.Map[mutable.WrappedArray[String],String]) =
udf((input: mutable.WrappedArray[String]) => lookupMap.lift(input))
//call the function
val combinedDF = mstrDataFrame.withColumn("ENTP_CLS_CD",lookup(lookupMap)(array($"SRC_SYS_CD",$"ORG_ID",$"ORG_CD")))
你应该
+----------+------+------+-----------+
|SRC_SYS_CD|ORG_ID|ORG_CD|ENTP_CLS_CD|
+----------+------+------+-----------+
|a |b |c |8 |
+----------+------+------+-----------+