【问题标题】:Spark DataFrame: converting 144 columns into rowSpark DataFrame:将 144 列转换为行
【发布时间】:2021-09-25 14:14:46
【问题描述】:

环境:Spark 2.4.0;斯卡拉

我从具有 144 列的 CSV 创建了 DF。有没有办法把除一列以外的所有列改成行?

Table A 
|dt  |AA|BB|CC|     
|----|--|--|--|
|1012|10|12|13|        
|1013|13|14|15|
|1014|14|18|30|


Table B (After transform Table A) 

|dt  |Head|Val|
|----|----|---
|1012|AA  |12|
|1013|AA  |13|
|1014|AA  |14|
|1012|BB  |12|
|1013|BB  |14|
|1014|BB  |18|
|1012|CC  |13|
|1013|CC  |15|
|1014|CC  |30|

我需要将表 A 转置/取消透视表 B。请注意,表 A 有 144 列。我认为内置函数 stack(n, expr1, ..., exprk) 但我不知道如何自动传递这么多列。

感谢您提供帮助的时间和精力。

【问题讨论】:

    标签: dataframe apache-spark pivot-table sparse-matrix unpivot


    【解决方案1】:

    您可以使用 Scala 字符串操作为stack 动态创建参数列表:

    val dfA = Seq((1012, 10, 12, 13), (1013, 13, 14, 15), (1014, 14, 18, 30)).toDF("dt", "AA", "BB", "CC")
    
    val columns = dfA.columns.filter(!_.equalsIgnoreCase("dt"))
    var cmd = s"stack(${columns.length},"
    for( col <- columns) cmd += s"'$col',$col,"
    cmd = cmd.dropRight(1) + ")"
    
    val dfB = dfA.selectExpr("dt", cmd)
      .withColumnRenamed("col0", "Head")
      .withColumnRenamed("col1", "Val")
    

    结果:

    +----+----+---+
    |  dt|Head|Val|
    +----+----+---+
    |1012|  AA| 10|
    |1012|  BB| 12|
    |1012|  CC| 13|
    |1013|  AA| 13|
    |1013|  BB| 14|
    |1013|  CC| 15|
    |1014|  AA| 14|
    |1014|  BB| 18|
    |1014|  CC| 30|
    +----+----+---+
    

    【讨论】:

    • 谢谢@werner。你的解决方案奏效了。我只是想在我的实际 DF 的列名中删除一些特殊的字符。感谢您的帮助
    【解决方案2】:

    问题的答案是如何自动处理 DF 中的所有列。

    val columnsToConcat: Array[String] = df.schema.fieldNames.filter(_ == "yourSingleColToExclude")
    df.select("yourSingleColToExclude", concat_ws("separator", columnsToConcat.map(col):_*))
    

    但我不知道stack 功能的局限性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-01
      • 2018-04-17
      • 2017-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多