首页 > 解决方案 > 映射函数中的数组操作:Spark 1.6

问题描述

我有一列是结构类型的包装数组,带有一个整数和一个双精度值。

架构如下所示:

 |-- pricing_data: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- _1: integer (nullable = false)
 |    |    |-- _2: double (nullable = false)

因此,每当此列值为 [[0,0.0]] 时,我都需要将其更改为空数组。[[0,0.0]] -> [[]]。

我怎样才能使用地图做到这一点?或使用数据框?

标签: scaladataframeapache-sparkuser-defined-functions

解决方案


尝试这个- spark>=2.4

   val df = Seq(Seq((0, 0.0)), Seq((1, 2.2))).toDF("pricing_data")
    df.show(false)
    df.printSchema()

    /**
      * +------------+
      * |pricing_data|
      * +------------+
      * |[[0, 0.0]]  |
      * |[[1, 2.2]]  |
      * +------------+
      *
      * root
      * |-- pricing_data: array (nullable = true)
      * |    |-- element: struct (containsNull = true)
      * |    |    |-- _1: integer (nullable = false)
      * |    |    |-- _2: double (nullable = false)
      */

    df.withColumn("pricing_data", expr(
    "TRANSFORM(pricing_data, x -> if(x._1=0 and x._2=0.0, named_struct('_1', null, '_2', null), x))"
    ))
      .show(false)

    /**
      * +------------+
      * |pricing_data|
      * +------------+
      * |[[,]]       |
      * |[[1, 2.2]]  |
      * +------------+
      */

spark<2.4

 // spark<2.4
    val dataType = df.schema("pricing_data").dataType
   val replace =  udf((arrayOfStruct: mutable.WrappedArray[Row]) => {
      arrayOfStruct.map(row => {
        val map = row.getValuesMap(row.schema.map(_.name))
        if(map("_1")==0 && map("_2") == 0.0) {
          Row.fromTuple((null, null))
        } else row
      })
    }, dataType)

    df.withColumn("pricing_data", replace($"pricing_data"))
        .show(false)

    /**
      * +------------+
      * |pricing_data|
      * +------------+
      * |[[,]]       |
      * |[[1, 2.2]]  |
      * +------------+
      */

推荐阅读