gpt4 book ai didi

scala - 从 Spark DataFrame 中的单个列派生多个列

转载 作者:行者123 更新时间:2023-12-03 06:07:36 25 4
gpt4 key购买 nike

我有一个 DF,其中包含巨大的可解析元数据作为 Dataframe 中的单个字符串列,我们将其称为 DFA,带有 ColmnA。

我想通过函数 ClassXYZ = Func1(ColmnA) 将这一列 ColmnA 分解为多个列。该函数返回一个类 ClassXYZ,具有多个变量,并且每个变量现在都必须映射到新的 Column,例如 ColmnA1、ColmnA2 等。

我如何通过仅调用此 Func1 一次来执行从 1 个数据帧到另一个具有这些附加列的数据帧的转换,而不必重复它来创建所有列。

如果我每次都调用这个巨大的函数来添加新列,那么解决起来很容易,但这是我希望避免的。

请提供工作代码或伪代码。

谢谢

桑杰

最佳答案

一般来说,你想要的东西是不可能直接实现的。 UDF 此时只能返回单个列。有两种不同的方法可以克服此限制:

  1. 返回复杂类型的列。最通用的解决方案是 StructType,但您也可以考虑 ArrayTypeMapType

    import org.apache.spark.sql.functions.udf

    val df = Seq(
    (1L, 3.0, "a"), (2L, -1.0, "b"), (3L, 0.0, "c")
    ).toDF("x", "y", "z")

    case class Foobar(foo: Double, bar: Double)

    val foobarUdf = udf((x: Long, y: Double, z: String) =>
    Foobar(x * y, z.head.toInt * y))

    val df1 = df.withColumn("foobar", foobarUdf($"x", $"y", $"z"))
    df1.show
    // +---+----+---+------------+
    // | x| y| z| foobar|
    // +---+----+---+------------+
    // | 1| 3.0| a| [3.0,291.0]|
    // | 2|-1.0| b|[-2.0,-98.0]|
    // | 3| 0.0| c| [0.0,0.0]|
    // +---+----+---+------------+

    df1.printSchema
    // root
    // |-- x: long (nullable = false)
    // |-- y: double (nullable = false)
    // |-- z: string (nullable = true)
    // |-- foobar: struct (nullable = true)
    // | |-- foo: double (nullable = false)
    // | |-- bar: double (nullable = false)

    这可以很容易地在以后展平,但通常没有必要。

  2. 切换到 RDD, reshape 并重建 DF:

    import org.apache.spark.sql.types._
    import org.apache.spark.sql.Row

    def foobarFunc(x: Long, y: Double, z: String): Seq[Any] =
    Seq(x * y, z.head.toInt * y)

    val schema = StructType(df.schema.fields ++
    Array(StructField("foo", DoubleType), StructField("bar", DoubleType)))

    val rows = df.rdd.map(r => Row.fromSeq(
    r.toSeq ++
    foobarFunc(r.getAs[Long]("x"), r.getAs[Double]("y"), r.getAs[String]("z"))))

    val df2 = sqlContext.createDataFrame(rows, schema)

    df2.show
    // +---+----+---+----+-----+
    // | x| y| z| foo| bar|
    // +---+----+---+----+-----+
    // | 1| 3.0| a| 3.0|291.0|
    // | 2|-1.0| b|-2.0|-98.0|
    // | 3| 0.0| c| 0.0| 0.0|
    // +---+----+---+----+-----+

关于scala - 从 Spark DataFrame 中的单个列派生多个列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32196207/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com