如何解决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?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。