我有一个表格的DataFrame:
A_DF = |id_A: Int|concatCSV: String|
另一个:
B_DF = |id_B: Int|triplet: List[String]|
concatCSV
的示例可能如下所示:
"StringD, StringB, StringF, StringE, StringZ"
"StringA, StringB, StringX, StringY, StringZ"
...
虽然triplet
类似于:
("StringA", "StringF", "StringZ")
("StringB", "StringU", "StringR")
...
我想制作A_DF
和B_DF
的 cartesian 集,例如;
| id_A: Int | concatCSV: String | id_B: Int | triplet: List[String] |
| 14 | "StringD, StringB, StringF, StringE, StringZ" | 21 | ("StringA", "StringF", "StringZ")|
| 14 | "StringD, StringB, StringF, StringE, StringZ" | 45 | ("StringB", "StringU", "StringR")|
| 18 | "StringA, StringB, StringX, StringY, StringG" | 21 | ("StringA", "StringF", "StringZ")|
| 18 | "StringA, StringB, StringX, StringY, StringG" | 45 | ("StringB", "StringU", "StringR")|
| ... | | | |
然后只保留StringA, StringB
中出现的A_DF("concatCSV")
至少有两个子串(例如B_DF("triplet")
)的记录,即使用{{1}排除那些不满足条件的人。
第一个问题是:我可以在不将DF转换为RDD的情况下执行此操作吗?
第二个问题是:我可以理想地在filter
步骤中完成整个事情 - 作为join
条件吗?
我尝试过类似的尝试:
where
但无法解析val cartesianRDD = A_DF
.join(B_DF,"right")
.where($"triplet".exists($"concatCSV".contains(_)))
。我用where
代替filter
尝试了它,但仍然没有运气。此外,由于某些奇怪的原因,where
的注释类型为cartesianRDD
,而不是SchemaRDD
。我是怎么做到的?最后,我在上面尝试的内容(我编写的短代码)是不完整的,因为它只保留DataFrame
中concatCSV
中triplet
的一个子字符串的记录。
所以,第三个问题是:我应该更改为RDD并使用自定义过滤功能解决它吗?
最后,最后一个问题:我可以在DataFrames中使用自定义过滤功能吗?
感谢您的帮助。
答案 0 :(得分:3)
函数CROSS JOIN
已在Hive
中实现,因此您可以先使用Hive SQL
进行交叉联接:
A_DF.registerTempTable("a")
B_DF.registerTempTable("b")
// sqlContext should be really a HiveContext
val result = sqlContext.sql("SELECT * FROM a CROSS JOIN b")
然后,您可以使用两个udf
过滤到预期的输出。一个将您的字符串转换为单词数组,另一个为我们提供结果数组列和现有列{{1}的交集的长度 }:
"triplet"