如何请求DataFrame的深拷贝-而无需完全重新计算原始DataFrame内容?
目的是在Spark Stream上执行自联接。
答案 0 :(得分:1)
数据帧是不可变的。这意味着您不必执行深层复制,您可以多次重复使用它们,并且在每次操作时都会创建新的数据框,而原始数据将保持不变。
例如:
val df = List((1),(2),(3)).toDF("id")
val df1 = df.as("df1") //second dataframe
val df2 = df.as("df2") //third dataframe
df1.join(df2, $"df1.id" === $"df2.id") //fourth dataframe and df is still unmodified
这似乎是对资源的浪费,但是由于数据框中的所有数据也是不可变的,因此所有四个数据框都可以重用对其中的对象的引用。
答案 1 :(得分:1)
常用方法:
val asdfDF = Seq((1, "a"), (2, "b"), (3, "c")).toDF("id", "text")
val columns = asdfDF.schema.fields.map(_.name).toSeq
val column0 = columns.head
val columnsRest = columns.tail
val columnTemp = column0 + UUID.randomUUID().toString
val asdfDF2 = asdfDF
.withColumn(columnTemp, col(column0))
.drop(column0)
.withColumnRenamed(columnTemp, column0)
.select(column0, columnsRest: _*)
asdfDF
.join(asdfDF2,
asdfDF("id") === (asdfDF2("id") - 1)
, "inner")
.show()
简短替代:
val asdfDF = Seq(1, 2, 3).toDF("id")
val asdfDF2 = asdfDF
.withColumn("id2", $"id")
.select($"id2".as("id"))
asdfDF
.join(asdfDF2,
asdfDF("id") === (asdfDF2("id") - 1)
, "inner")
.show()
此代码产生以下输出:
+---+----+---+----+
| id|text| id|text|
+---+----+---+----+
| 1| a| 2| b|
| 2| b| 3| c|
+---+----+---+----+