scala – 从Spark DataFrame中的单个列派生多个列
发布时间:2020-12-16 09:47:23 所属栏目:安全 来源:网络整理
导读:我有一个DF与巨大的可剖析元数据作为单个字符串列在Dataframe,让它称为DFA,与ColmnA。 我想打破这一列,ColmnA通过一个函数,多个列,ClassXYZ = Func1(ColmnA)。这个函数返回一个ClassXYZ类,有多个变量,这些变量现在必须映射到新的Column,例如ColmnA1
我有一个DF与巨大的可剖析元数据作为单个字符串列在Dataframe,让它称为DFA,与ColmnA。
我想打破这一列,ColmnA通过一个函数,多个列,ClassXYZ = Func1(ColmnA)。这个函数返回一个ClassXYZ类,有多个变量,这些变量现在必须映射到新的Column,例如ColmnA1,ColmnA2等。 我如何通过调用Func1只做一次,从1个Dataframe到另一个使用这些附加列的转换,而不必重复 – 创建所有列。 它很容易解决,如果我每次都调用这个巨大的函数添加一个新的列,但是我想避免。 请告诉我一个工作或伪代码。 谢谢 Sanjay 解决方法
一般来说,你想要的不是直接可能的。 UDF只能在当时返回单个列。有两种不同的方法可以克服这个限制:
>返回复杂类型的列。最通用的解决方案是StructType,但您也可以考虑ArrayType或MapType。 import org.apache.spark.sql.functions.udf val df = sc.parallelize(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) 这可以很容易地平坦后,但通常没有必要这样。 import org.apache.spark.sql.types._ import org.apache.spark.sql.Row def foobarFunc(x: Long,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| // +---+----+---+----+-----+ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |