如何使用Scala在Spark Dataframes中比较两列数据

时间:2018-07-20 07:14:12

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

我想比较Spark DataFrame中的两列:如果在另一个(attr_value)的值中找到一列(attr_valuelist)的值,则只希望该值被保存。否则,列值应为null

例如,给出以下输入

id1 id2   attrname  attr_value   attr_valuelist
1   2     test      Yes          Yes, No
2   1     test1     No           Yes, No
3   2     test2     value1       val1, Value1,value2

我期望以下输出

id1 id2   attrname  attr_value   attr_valuelist
1   2     test      Yes          Yes
2   1     test1     No           No
3   2     test2     value1       Value1

2 个答案:

答案 0 :(得分:1)

您可以尝试使用此代码吗?我认为它可以在SQL包含大小写的情况下使用。

val emptyRDD = sc.emptyRDD[Row] 

var emptyDataframe = sqlContext.createDataFrame(emptyRDD, your_dataframe.schema)

your_dataframe.createOrReplaceTempView("tbl")  

emptyDataframe = sqlContext.sql("select id1, id2, attrname, attr_value, case when
attr_valuelist like concat('%', attr_value, '%') then attr_value else
null end as attr_valuelist from tbl") 

emptyDataframe.show

答案 1 :(得分:1)

在给定您的示例输入的情况下,我假设包含搜索项的列包含一个字符串,而搜索目标是一个字符串序列。另外,我假设您对不区分大小写的搜索感兴趣。

这将是输入(我添加了一个会产生null的列来测试我编写的UDF的行为)

+---+---+--------+----------+----------------------+
|id1|id2|attrname|attr_value|attr_valuelist        |
+---+---+--------+----------+----------------------+
|1  |2  |test    |Yes       |[Yes, No]             |
|2  |1  |test1   |No        |[Yes, No]             |
|3  |2  |test2   |value1    |[val1, Value1, value2]|
|3  |2  |test2   |value1    |[val1, value2]        |
+---+---+--------+----------+----------------------+

您可以使用非常简单的UDF解决问题。

val find = udf {
  (item: String, collection: Seq[String]) =>
    collection.find(_.toLowerCase == item.toLowerCase)
}

val df = spark.createDataFrame(Seq(
  (1, 2, "test", "Yes", Seq("Yes", "No")),
  (2, 1, "test1", "No", Seq("Yes", "No")),
  (3, 2, "test2", "value1", Seq("val1", "Value1", "value2")),
  (3, 2, "test2", "value1", Seq("val1", "value2"))
)).toDF("id1", "id2", "attrname", "attr_value", "attr_valuelist")

df.select(
  $"id1", $"id2", $"attrname", $"attr_value",
  find($"attr_value", $"attr_valuelist") as "attr_valuelist")

show输入最后一条命令的输出将产生以下输出:

+---+---+--------+----------+--------------+
|id1|id2|attrname|attr_value|attr_valuelist|
+---+---+--------+----------+--------------+
|  1|  2|    test|       Yes|           Yes|
|  2|  1|   test1|        No|            No|
|  3|  2|   test2|    value1|        Value1|
|  3|  2|   test2|    value1|          null|
+---+---+--------+----------+--------------+

您可以在任何spark-shell中执行此代码。如果要在要提交到群集的作业中使用此功能,请记住要import spark.implicits._