scala 根据具有相同值的 2 列过滤掉连接 df 中的行 - 最佳方式
Posted
技术标签:
【中文标题】scala 根据具有相同值的 2 列过滤掉连接 df 中的行 - 最佳方式【英文标题】:scala filtering out rows in a joined df based on 2 columns with same values - best way 【发布时间】:2019-01-06 19:29:16 【问题描述】:我正在比较 2 个数据帧。 我选择逐列比较它们
我从父数据框创建了 2 个较小的数据框。 基于连接列和比较列:
Created 1st dataframe:
val df1_subset = df1.select(subset_cols.head, subset_cols.tail: _*)
+----------+---------+-------------+
|first_name|last_name|loyalty_score|
+----------+---------+-------------+
| tom | cruise| 66|
| blake | lively| 66|
| eva| green| 44|
| brad| pitt| 99|
| jason| momoa| 34|
| george | clooney| 67|
| ed| sheeran| 88|
| lionel| messi| 88|
| ryan| reynolds| 45|
| will | smith| 67|
| null| null| |
+----------+---------+-------------+
Created 2nd Dataframe:
val df1_1_subset = df1_1.select(subset_cols.head, subset_cols.tail: _*)
+----------+---------+-------------+
|first_name|last_name|loyalty_score|
+----------+---------+-------------+
| tom | cruise| 34|
| brad| pitt| 78|
| eva| green| 56|
| tom | cruise| 99|
| jason| momoa| 34|
| george | clooney| 67|
| george | clooney| 88|
| lionel| messi| 88|
| ryan| reynolds| 45|
| will | smith| 67|
| kyle| jenner| 56|
| celena| gomez| 2|
+----------+---------+-------------+
然后我加入了 2 个子集 我将这些作为完全外部连接加入以获得以下结果:
val df_subset_joined = df1_subset.join(df1_1_subset, joinColsArray, "full_outer")
Joined Subset
+----------+---------+-------------+-------------+
|first_name|last_name|loyalty_score|loyalty_score|
+----------+---------+-------------+-------------+
| will | smith| 67| 67|
| george | clooney| 67| 67|
| george | clooney| 67| 88|
| blake | lively| 66| null|
| celena| gomez| null| 2|
| eva| green| 44| 56|
| null| null| | null|
| jason| momoa| 34| 34|
| ed| sheeran| 88| null|
| lionel| messi| 88| 88|
| kyle| jenner| null| 56|
| tom | cruise| 66| 34|
| tom | cruise| 66| 99|
| brad| pitt| 99| 78|
| ryan| reynolds| 45| 45|
+----------+---------+-------------+-------------+
然后我尝试使用列位置过滤掉两个比较列中相同的元素(本例中为loyalty_scores)
df_subset_joined.filter(_c2 != _c3).show
但这没有用。我收到以下错误:
Error:(174, 33) not found: value _c2
df_subset_joined.filter(_c2 != _c3).show
对我来说,获得连接数据框的最有效方法是什么,我只能看到比较列中不匹配的行。
我想保持这种动态,所以硬编码列名不是一种选择。
感谢您帮助我理解这一点。
【问题讨论】:
【参考方案1】:您需要使用别名并使我们成为空安全比较运算符 (https://spark.apache.org/docs/latest/api/sql/index.html#_9),另请参阅 https://***.com/a/54067477/1138523
val df_subset_joined = df1_subset.as("a").join(df1_1_subset.as("b"), joinColsArray, "full_outer")
df_subset_joined.filter(!($"a.loyality_score" <=> $"b.loyality_score")).show
编辑:对于动态列名,您可以使用字符串插值
import org.apache.spark.sql.functions.col
val xxx : String = ???
df_subset_joined.filter(!(col(s"a.$xxx") <=> col(s"b.$xxx"))).show
【讨论】:
谢谢。但我想避免列名的硬编码。这就是我的全部挑战。有没有办法使用:df_subset_joined.filter($"a.XXX" =!= $"b.XXX").show 其中XXX是一个动态值 这对我不起作用,但确实如此:val filter_str = (s"a.$col")+" != "+s"b.$col" df_subset_joined.filter(filter_str)。显示您的答案绝对是正确的方向。 @banditKing 可以尝试获取我的答案,我使用了错误的相等运算符以上是关于scala 根据具有相同值的 2 列过滤掉连接 df 中的行 - 最佳方式的主要内容,如果未能解决你的问题,请参考以下文章