将struct字段与另一列进行比较

k97glaaz  于 2021-05-18  发布在  Spark
关注(0)|答案(1)|浏览(451)

我有一个带有arraytype struct field的数据集,我需要过滤stat字段中与max\u stat值一致的值。数据结构如下所示:

|-- data: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- id: integer (nullable = true)
 |    |    |-- stat: float (nullable = true)
 |-- max_stat: float (nullable = true)
 |-- naming: string (nullable = true)

我试着这样做,但无法将数组与int进行比较。那么如何更改此筛选器?

df.filter($"data.stat" === "max_stat")
.drop(max_stat)

输入数据:

data                           | max_stat | naming
[(1,0.34),(2, 0.57), (3, 0.89)] | 0.89     | example

预期产量:

data     | naming
(3, 0.89) | example
gudnpqoy

gudnpqoy1#

你必须使用 explode 以便为每个 elementdata .

import org.apache.spark.sql.functions.explode

ds
  .withColumn("data", explode($"data"))
  .filter($"data.stat" === $"max_stat")
  .drop($"max_stat")
  .show()

输出:

+---------+-------+
|     data| naming|
+---------+-------+
|[3, 0.89]|example|
+---------+-------+

然而, explode 这是一个非常昂贵的操作,如果您的数据集很大,这可能是一个问题。不使用explode的另一种方法是:

import org.apache.spark.sql.functions._

ds
  .filter(array_contains($"data.stat", $"max_stat"))
  .withColumn("max_stat_idx", array_position($"data.stat", $"max_stat").cast(IntegerType))
  .withColumn("data", element_at($"data", $"max_stat_idx"))
  .drop("max_stat", "max_stat_idx")

基本上,它是在 data 数组,然后使用此索引 element

相关问题