我有一个包含一列数组字符串的数据框 A。
...
|-- browse: array (nullable = true)
| |-- element: string (containsNull = true)
...
例如,三个样本行将是
+---------+--------+---------+
| column 1| browse| column n|
+---------+--------+---------+
| foo1| [X,Y,Z]| bar1|
| foo2| [K,L]| bar2|
| foo3| [M]| bar3|
另一个包含一列字符串的Dataframe B
|-- browsenodeid: string (nullable = true)
它的一些示例行将是
+------------+
|browsenodeid|
+------------+
| A|
| Z|
| M|
如何过滤 A 以便保留
browse
的所有行包含 browsenodeid
的任何值来自 B?根据上述示例,结果将是:+---------+--=-----+---------+
| column 1| browse| column n|
+---------+--------+---------+
| foo1| [X,Y,Z]| bar1| <- because Z is a value of B.browsenodeid
| foo3| [M]| bar3| <- because M is a value of B.browsenodeid
如果我有一个值,那么我会使用类似的东西
A.filter(array_contains(A("browse"), single_value))
但是我该如何处理值的列表或 DataFrame 呢?
最佳答案
我为此找到了一个优雅的解决方案,无需转换 DataFrame
s/Dataset
转至 RDD
s。
假设你有一个 DataFrame dataDF
:
+---------+--------+---------+
| column 1| browse| column n|
+---------+--------+---------+
| foo1| [X,Y,Z]| bar1|
| foo2| [K,L]| bar2|
| foo3| [M]| bar3|
和一个数组 b
包含您要在 browse
中匹配的值val b: Array[String] = Array(M,Z)
实现 udf:import org.apache.spark.sql.expressions.UserDefinedFunction
import scala.collection.mutable.WrappedArray
def array_contains_any(s:Seq[String]): UserDefinedFunction = {
udf((c: WrappedArray[String]) =>
c.toList.intersect(s).nonEmpty)
}
然后只需使用 filter
或 where
函数(带有一点花哨的柯里化(Currying):P)来进行过滤,例如:dataDF.where(array_contains_any(b)($"browse"))
关于apache-spark - 如何按包含其他数据帧/集的任何值的数组列过滤 Spark 数据帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43904622/