【问题标题】:Spark dataframe UDF Filter in array数组中的 Spark 数据框 UDF 过滤器
【发布时间】:2018-07-15 17:02:19
【问题描述】:

我想定义一个 UDF 函数来过滤 Spark 中的 DataFrame。 我想在每一列中过滤一个数组元素。

示例:过滤以'Z'开头的元素,删除数组中所有不以Z开头的元素

Original Data
+---+-------------+
| _1|           _2|
+---+-------------+
|id1|[AA,BB,CC,Z12]|
|id2|[AA,ZA,CC,Z3]|
|id2|[Z2,XX,CC,A2]|
+---+-------------+
Expected result
+---+-----------+
| _1| _2        |
+---+-----------+
|id1| [Z12]     |
|id2| [ZA,Z3]   |
|id2| [Z2]      |
+---+-----------+
Current result
+---+--------------+
| _1| _2           |
+---+--------------+
|id1| []           |
|id2| []           |
|id2| [Z2,XX,CC,A2]|
+---+--------------+

当前代码

def filterArray = udf((recs: Seq[String]) =>{
    recs.filter(_.startsWith("Z"))
})

val rawData = Seq(("id1",Array("AA,BB,CC,Z12")),("id2",Array("AA,ZA,CC,Z3")),("id2",Array("AA,XX,CC,A2")))
var test = spark.createDataFrame(rawData)
test.show(4)
test = test.withColumn("_2", filterArray(test("_2")))
test.show(4)

【问题讨论】:

  • 你给出的解决方案有问题吗?

标签: apache-spark dataframe


【解决方案1】:

问题是你的数组都只有 1 个元素,你应该先拆分包含的字符串,然后过滤:

def filterArray = udf((recs: Seq[String]) =>{
  recs.flatMap(_.split(",")).filter(_.startsWith("Z"))
})

然后你得到

+---+--------+
| _1|      _2|
+---+--------+
|id1|   [Z12]|
|id2|[ZA, Z3]|
|id2|      []|
+---+--------+

如果数据定义如下,您可以保留当前的 ​​UDF:

val rawData = Seq(
   ("id1",Array("AA","BB","CC","Z12")), 
   ("id2",Array("AA","ZA","CC","Z3")), 
   ("id2",Array("AA","XX","CC","A2"))
 )

【讨论】:

    猜你喜欢
    • 2020-05-16
    • 2018-08-01
    • 1970-01-01
    • 2023-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 2020-12-17
    相关资源
    最近更新 更多