需要帮助比较spark scala中的两列吗

需要帮助比较spark scala中的两列吗,scala,apache-spark,Scala,Apache Spark,我有一个像这样的数据框 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 4 1 test3 3 0, 1, 2 5 3 test4 0

我有一个像这样的数据框

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
4    1  test3         3        0, 1, 2
5    3  test4         0        0, 1, 2
11   2  test         Yes      Yes, No
22   1  test1        No1       Yes, No
33   2  test2       value0    val1, Value1,value2
44   1  test3         11        0, 1, 2
55   3  test4         0        0, 1, 2

val df = sqlContext.sql("select id1, id2, attrname, attr_value, attr_valuelist from dftable)
df.where(contains(df("attr_value", df("attr_valuelist")))
df.where(notContains(df("attr_value", df("attr_valuelist")))
我想检查attr_valuelist中的attr_值,如果它不存在,则只取那些行

id1 id2 attrname attr_value attr_valuelist
4    1  test3         3        0, 1, 2
22   1  test1        No1       Yes, No
33   2  test2       value0    val1, Value1,value2
44   1  test3         11        0, 1, 2

您可以在Spark中定义自定义函数,即用户定义函数,在该函数中,您可以测试一列中的值是否包含在另一列的值中,如下所示:

def contains = udf((attr: String, attrList: String) => attrList.contains(attr))
def notContains = udf((attr: String, attrList: String) => !attrList.contains(attr))
您可以根据需要调整包含函数,然后可以像这样从数据帧中进行选择

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
4    1  test3         3        0, 1, 2
5    3  test4         0        0, 1, 2
11   2  test         Yes      Yes, No
22   1  test1        No1       Yes, No
33   2  test2       value0    val1, Value1,value2
44   1  test3         11        0, 1, 2
55   3  test4         0        0, 1, 2

val df = sqlContext.sql("select id1, id2, attrname, attr_value, attr_valuelist from dftable)
df.where(contains(df("attr_value", df("attr_valuelist")))
df.where(notContains(df("attr_value", df("attr_valuelist")))

您可以在Spark中定义自定义函数,即用户定义函数,在该函数中,您可以测试一列中的值是否包含在另一列的值中,如下所示:

def contains = udf((attr: String, attrList: String) => attrList.contains(attr))
def notContains = udf((attr: String, attrList: String) => !attrList.contains(attr))
您可以根据需要调整包含函数,然后可以像这样从数据帧中进行选择

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
4    1  test3         3        0, 1, 2
5    3  test4         0        0, 1, 2
11   2  test         Yes      Yes, No
22   1  test1        No1       Yes, No
33   2  test2       value0    val1, Value1,value2
44   1  test3         11        0, 1, 2
55   3  test4         0        0, 1, 2

val df = sqlContext.sql("select id1, id2, attrname, attr_value, attr_valuelist from dftable)
df.where(contains(df("attr_value", df("attr_valuelist")))
df.where(notContains(df("attr_value", df("attr_valuelist")))

您可以简单地使用数据帧中的contains执行以下操作

import org.apache.spark.sql.functions._
df.filter(!(col("attr_valuelist").contains(col("attr_value")))).show(false)
您应该有以下输出

+---+---+--------+----------+-------------------+
|id1|id2|attrname|attr_value|attr_valuelist     |
+---+---+--------+----------+-------------------+
|3  |2  |test2   |value1    |val1, Value1,value2|
|4  |1  |test3   |3         |0, 1, 2            |
|22 |1  |test1   |No1       |Yes, No            |
|33 |2  |test2   |value0    |val1, Value1,value2|
|44 |1  |test3   |11        |0, 1, 2            |
+---+---+--------+----------+-------------------+
如果您想忽略大小写字母,则只需使用
lower
函数即可

df.filter(!(lower(col("attr_valuelist")).contains(lower(col("attr_value"))))).show(false)
你应该

+---+---+--------+----------+-------------------+
|id1|id2|attrname|attr_value|attr_valuelist     |
+---+---+--------+----------+-------------------+
|4  |1  |test3   |3         |0, 1, 2            |
|22 |1  |test1   |No1       |Yes, No            |
|33 |2  |test2   |value0    |val1, Value1,value2|
|44 |1  |test3   |11        |0, 1, 2            |
+---+---+--------+----------+-------------------+

您可以简单地使用数据帧中的contains执行以下操作

import org.apache.spark.sql.functions._
df.filter(!(col("attr_valuelist").contains(col("attr_value")))).show(false)
您应该有以下输出

+---+---+--------+----------+-------------------+
|id1|id2|attrname|attr_value|attr_valuelist     |
+---+---+--------+----------+-------------------+
|3  |2  |test2   |value1    |val1, Value1,value2|
|4  |1  |test3   |3         |0, 1, 2            |
|22 |1  |test1   |No1       |Yes, No            |
|33 |2  |test2   |value0    |val1, Value1,value2|
|44 |1  |test3   |11        |0, 1, 2            |
+---+---+--------+----------+-------------------+
如果您想忽略大小写字母,则只需使用
lower
函数即可

df.filter(!(lower(col("attr_valuelist")).contains(lower(col("attr_value"))))).show(false)
你应该

+---+---+--------+----------+-------------------+
|id1|id2|attrname|attr_value|attr_valuelist     |
+---+---+--------+----------+-------------------+
|4  |1  |test3   |3         |0, 1, 2            |
|22 |1  |test1   |No1       |Yes, No            |
|33 |2  |test2   |value0    |val1, Value1,value2|
|44 |1  |test3   |11        |0, 1, 2            |
+---+---+--------+----------+-------------------+

谢谢Ramesh,但我看到上面的示例也会选择列,如果我有像这样的值id1 | id2 | attrname | attr | u value | attr | u valuelist--------------------------------------------------------------------------------44 | 1 | test3 | 1 | 10,11,12 attr | u valuelist不是数组,它是字符串,您测试过它吗?我添加了上面的行,它被过滤掉了。我也将attr_valuelist视为字符串,而不是数组。很抱歉,我是通过sql进行测试的,所以这是真的,我也不明白。非常感谢你。我无法点击“接受答案”。过段时间我会做的。你可以随时接受。记住当你有资格的时候也要投票当然我会这么做,谢谢Ramesh,但我看到上面的示例也会选择列,如果我有像这样的值,id1 | id2 | attrname | attr | u value | attr | u valuelist-------------------------------------------------------44 | 1 | test3 | 1 | 10,11,12 attr | u valuelist不是数组,它是字符串,您测试了吗?我添加了上面的行,它被过滤掉了。我也将attr_valuelist视为字符串,而不是数组。很抱歉,我是通过sql进行测试的,所以这是真的,我也不明白。非常感谢你。我无法点击“接受答案”。过段时间我会做的。你可以随时接受。记住当你有资格的时候也要投票我当然会那样做