【问题标题】:Compare struct field to another column Spark将结构字段与另一列 Spark 进行比较
【发布时间】:2020-11-07 03:29:54
【问题描述】:

我有一个带有 ArrayType 结构字段的数据集,我需要过滤与 max_stat 值一致的 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)

我试图做这样的事情,但无法将 Array 与 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

【问题讨论】:

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


    【解决方案1】:

    您必须使用explode 才能为data 中的每个element 生成一行。

    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

    【讨论】:

    • 由于某种原因,我在使用爆炸解决方案时遇到此错误org.apache.spark.sql.AnalysisException: Can't extract value from data#2151. data AS data#2493: need struct type but got int
    • 你用的是什么火花版本?此外,您的架构很奇怪:max_stat 的类型为 integer,但在您的示例中 max_stat 是双精度。
    • 我解决了我的问题,max_stat 实际上是浮动的。另外,我混淆了堆栈跟踪中字段的命名,它看起来像这样:Can't extract value from data#2151. id AS id#2493: need struct type but got int
    • 你能提供ds.limit(1).show的输出吗?您的数据可能不符合架构。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    相关资源
    最近更新 更多