Учитывая dataFrame с несколькими столбцами, я пытаюсь создать новый столбец, содержащий массив имен этих столбцов, отсортированных по убыванию, на основе строковых значений этих столбцов.

| a | b | c | newcol|
|---|---|---|-------|
| 1 | 4 | 3 |[b,c,a]|
| 4 | 1 | 3 |[a,c,b]|
---------------------

Имена столбцов хранятся в именах переменных: Array [String]

Какой подход я должен пойти?

0
mobupu 5 Фев 2020 в 12:48

3 ответа

Лучший ответ

Использование UDF - это самый простой способ решения пользовательских задач.

val df = spark.createDataFrame(Seq((1,4,3), (4,1,3))).toDF("a", "b", "c")

val names=df.schema.fieldNames
val sortNames = udf((v: Seq[Int]) => {v.zip(names).sortBy(_._1).map(_._2)})
df.withColumn("newcol", sortNames(array(names.map(col): _*))).show
2
Artem Aliev 5 Фев 2020 в 12:45

Попробуйте что-то вроде этого:

val sorted_column_names = udf((column_map: Map[String, Int]) => 
    column_map.toSeq.sortBy(- _._2).map(_._1)
)
df.withColumn("column_map", map(lit("a"), $"a", lit("b"), $"b", lit("c"), $"c")
    .withColumn("newcol", sorted_column_names($"column_map"))
0
Niclas von Caprivi 5 Фев 2020 в 12:34

Примерно так может быть подход с использованием набора данных:

case class Element(name: String, value: Int)
case class Columns(a: Int, b: Int, c: Int, elements: Array[String])

def function1()(implicit spark: SparkSession) = {
    import spark.implicits._
    val df0: DataFrame =
      spark.createDataFrame(spark.sparkContext
        .parallelize(Seq(Row(1, 2, 3), Row(4, 1, 3))),
        StructType(Seq(StructField("a", IntegerType, false),
          StructField("b", IntegerType, false),
            StructField("c", IntegerType, false))))

    val df1 = df0
      .flatMap(row => Seq(Columns(row.getAs[Int]("a"),
        row.getAs[Int]("b"),
        row.getAs[Int]("c"),
        Array(Element("a", row.getAs[Int]("a")),
        Element("b", row.getAs[Int]("b")),
        Element("c", row.getAs[Int]("c"))).sortBy(-_.value).map(_.name))))

    df1
  }

 def main(args: Array[String]) : Unit = {
        implicit val spark = SparkSession.builder().master("local[1]").getOrCreate()
        function1().show()
 }

Дает:

+---+---+---+---------+
|  a|  b|  c| elements|
+---+---+---+---------+
|  1|  2|  3|[a, b, c]|
|  4|  1|  3|[b, c, a]|
+---+---+---+---------+
0
EmiCareOfCell44 5 Фев 2020 в 12:32