scala - 有没有办法为 Spark 数据帧添加额外的元数据?

标签 scala apache-spark apache-spark-sql

是否可以向 DataFrame 添加额外的元数据? ?

原因

我有星火 DataFrame我需要保留额外信息的 s。示例:A DataFrame ,为此我想“记住”整数 id 列中使用率最高的索引。

当前解决方案

我使用单独的 DataFrame来存储这些信息。当然,单独保存这些信息既乏味又容易出错。

是否有更好的解决方案将此类额外信息存储在 DataFrame 上? ?

最佳答案

为了扩展和 Scala-fy nealmcb 的答案(问题被标记为 scala,而不是 python,所以我认为这个答案不会偏离主题或多余),假设您有一个 DataFrame:

import org.apache.spark.sql
val df = sc.parallelize(Seq.fill(100) { scala.util.Random.nextInt() }).toDF("randInt")

以及一些获得最大值或任何你想在 DataFrame 上内存的方法:
val randIntMax = df.rdd.map { case sql.Row(randInt: Int) => randInt }.reduce(math.max)
sql.types.Metadata只能保存字符串、 bool 值、某些类型的数字和其他元数据结构。所以我们必须使用一个 Long:
val metadata = new sql.types.MetadataBuilder().putLong("columnMax", randIntMax).build()

DataFrame.withColumn() 实际上有一个允许在最后提供元数据参数的重载,但是它莫名其妙地被标记为 [private],所以我们只做它所做的——使用 Column.as(alias, metadata) :
val newColumn = df.col("randInt").as("randInt_withMax", metadata)
val dfWithMax = df.withColumn("randInt_withMax", newColumn)
dfWithMax现在有(一列)你想要的元数据!
dfWithMax.schema.foreach(field => println(s"${field.name}: metadata=${field.metadata}"))
> randInt: metadata={}
> randInt_withMax: metadata={"columnMax":2094414111}

或者以编程方式和类型安全(有点;Metadata.getLong() 和其他人不返回 Option 并可能抛出“找不到 key ”异常):
dfWithMax.schema("randInt_withMax").metadata.getLong("columnMax")
> res29: Long = 209341992

在您的情况下,将最大值附加到列是有意义的,但在将元数据附加到 DataFrame 而不是特别的列的一般情况下,您似乎必须采用其他答案描述的包装器路线。

关于scala - 有没有办法为 Spark 数据帧添加额外的元数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32628845/

相关文章:

scala - 在 scala 中的 Dataframe Join 中使用字符串函数

scala - Scala 2.9 REPL 的 settings.maxPrintString

apache-spark - 即使在 8 小时后,Spark 写入 CSV 也会失败

Scala/DataFrame/Spark : How do I express multiple conditional aggregates?

hadoop - 有效地在Spark中重用Hadoop代码?

scala - 如何在单元测试中抑制 Spark 日志记录?

scala - 限制数据帧分区的最大大小

scala - 使用 Akka Futures 并行生成随机数

scala - 如何在 Scala 中对大写和小写字符串进行排序

scala - 在不输入 amm 的情况下运行 Ammonite scala 脚本