scala根据2列具有相同值的列过滤出已合并df中的行-最佳方法

时间:2019-01-06 19:29:17

标签: scala apache-spark dataframe apache-spark-sql

我正在比较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 个答案:

答案 0 :(得分:1)

您需要使用别名并让我们使用null安全比较运算符(https://spark.apache.org/docs/latest/api/sql/index.html#_9),另请参见https://stackoverflow.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