DataFrame 中的列标题逆透视 (Spark Scala)

问题描述

我正在寻找一种有效的方法获取多列的标题,并将它们反旋转为一列。下面是一个例子:

我从一张看起来像这样的桌子开始。三列,每列一个标题

| Header 1| Header 2| Header 3 |
___________________________________ 
| null    | null    | null    |
| null    | null    | null    |
| null    | null    | null    |

我想做的是这个 ->

| Some Name   | Unique Name | Unique Name | Unique Name
_______________________________________________________
| Header 1    | null        | null        | null
| Header 2    | null        | null        | null
| Header 3    | null        | null        | null

我实际上是在尝试将每列中的标题名称转置为单个列中的它们自己的值,这将接收一个新的标题名称。该行中的每个值也将成为一个新列的一部分,该列将接收一个新的标题名称。我了解如何获取一列并使用 .pivot() 函数根据列的值创建新标题,但我在反向操作时遇到了麻烦。

我的研究表明,Python 有 .melt(),它可能是也可能不是这个问题的理想解决方案,但作为一个新的 Scala 开发人员并且第一次使用 Spark - 我可以使用一些建议来了解如何最好的方法。如果这比我想象的更简单,我深表歉意!

感谢您的所有帮助。

解决方法

看看 Scala 中的这种方法:

import org.apache.spark.sql.functions._

  def melt(
    df: DataFrame,idVars: Array[String],valueVars: Array[String],varName: String = "variable",valueName: String = "value"): DataFrame = {

    val columns = valueVars.map(c => Array(lit(c),col(c))).flatten
    val varsAndVals = map(columns: _*)
    df.select(idVars.map(col(_)).:+(explode(varsAndVals)): _*)
      .withColumnRenamed("key",varName)
      .withColumnRenamed("value",valueName)
  }

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

    val df = spark
      .createDataFrame(
        spark.sparkContext.parallelize(
          Seq(Row("a",1,2,null),Row("b",3,4,7),Row("c",5,6,9))),StructType(
              List(
                StructField("A",StringType),StructField("B",IntegerType),StructField("C",StructField("D",IntegerType))))

    melt(df,Array("A"),Array("B","C","D")).show()
  }

输入数据框:

+---+---+---+----+
|  A|  B|  C|   D|
+---+---+---+----+
|  a|  1|  2|null|
|  b|  3|  4|   7|
|  c|  5|  6|   9|
+---+---+---+----+

未旋转的 DF:

+---+--------+-----+
|  A|variable|value|
+---+--------+-----+
|  a|       B|    1|
|  a|       C|    2|
|  a|       D| null|
|  b|       B|    3|
|  b|       C|    4|
|  b|       D|    7|
|  c|       B|    5|
|  c|       C|    6|
|  c|       D|    9|
+---+--------+-----+

改编自这个问题How to melt Spark DataFrame?

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...