scala - 如何将数据框中的每一列转换为具有 ColumnName 和 ColumnValue 的行
问题描述
我需要转换以下数据框:
╔══════╦════════╦════════╦════════╗
║ Year ║ ColA ║ ColB ║ ColC ║
╠══════╬════════╬════════╬════════╣
║ 2017 ║ 1 ║ 2 ║ 3 ║
║ 2018 ║ 4 ║ 5 ║ 6 ║
║ 2019 ║ 7 ║ 8 ║ 9 ║
╚══════╩════════╩════════╩════════╝
进入这个:
╔══════╦════════╦═══════╗
║ Year ║ColName ║ Value ║
╠══════╬════════╬═══════╣
║ 2017 ║ ColA ║ 1 ║
║ 2017 ║ ColB ║ 2 ║
║ 2017 ║ ColC ║ 3 ║
║ 2018 ║ ColA ║ 4 ║
║ 2018 ║ ColB ║ 5 ║
║ 2018 ║ ColC ║ 6 ║
║ 2019 ║ ColA ║ 7 ║
║ 2019 ║ ColB ║ 8 ║
║ 2019 ║ ColC ║ 9 ║
╚══════╩════════╩═══════╝
这需要支持除第一个“年份”之外的任意数量的列,可以是 1 或多个。它应该是一个通用的解决方案,这意味着它不应该在任何地方使用硬编码的列名,而应该直接从原始数据帧中读取列名。
我正在使用带有用 Scala 编写的笔记本的 Databricks。Spark 和 Scala 都非常新。
更新
我在 Python 中找到了这个运行良好的解决方案,但我很难将它转换为 Scala。
def columnsToRows(df, by):
# Filter dtypes and split into column names and type description.
# Only get columns not in "by".
cols, dtypes = zip(*((c, t) for (c, t) in df.dtypes if c not in by))
# Create and explode an array of (column_name, column_value) structs
kvs = F.explode(F.array([
F.struct(F.lit(c.strip()).alias("ColName"), F.col(c).alias("Value")) for c in cols
])).alias("kvs")
return df.select(by + [kvs]).select(by + ["kvs.ColName", "kvs.Value"])
解决方案
您可以使用stack
转置数据
val fixedColumns = Seq("Year", "FixedColumn")
val cols = df.columns
.filter(c => !(fixedColumns.contains(c)))
.map(c => (s"'${c}', ${c}" ))
val exp= cols.mkString(s"stack(${cols.size}, ", "," , ") as (Point, Value)")
df.select($"Year", expr(exp))
输出:
+----+------+-----+
|Year|Point |Value|
+----+------+-----+
|2017|PointA|1 |
|2017|PointB|2 |
|2017|PointC|3 |
|2018|PointA|4 |
|2018|PointB|5 |
|2018|PointC|6 |
|2019|PointA|7 |
|2019|PointB|8 |
|2019|PointC|9 |
+----+------+-----+
推荐阅读
- reactjs - 如何修复键盘错误隐藏反应本机
- game-engine - 在 godot 中将 RichTextLabel 添加为子项时出现问题
- swift - 如何在 OSX 应用程序的本地主机上设置 HTTP 侦听器
- r - R简化了从全局变量中删除行的嵌套for循环
- javascript - Javascript .style 更改影响两个元素,尽管它们的值记录不同
- amazon-web-services - 查询 RDS 与查询 S3(ListObject) 关于性能
- c# - c#在gridview中获取绑定文本框的值(文本)
- javascript - 在 React.js 应用程序中从广告合作伙伴加载外部脚本
- php - 我正在尝试为我的网站创建登录系统,但出现意外错误
- c - 使用 char 类型作为标志?