繁体   English   中英

在 Apache Spark 1.3 中将一列附加到数据帧

[英]Append a column to Data Frame in Apache Spark 1.3

是否有可能以及将列添加到 Data Frame 的最有效的简洁方法是什么?

更具体地说,列可以用作现有数据框的行 ID。

在一个简化的情况下,从文件中读取而不是标记它,我可以想到以下内容(在 Scala 中),但它以错误完成(在第 3 行),无论如何看起来都不是最佳路线:

var dataDF = sc.textFile("path/file").toDF() 
val rowDF = sc.parallelize(1 to DataDF.count().toInt).toDF("ID") 
dataDF = dataDF.withColumn("ID", rowDF("ID")) 

我发布这个问题已经有一段时间了,似乎其他一些人也想得到答案。 下面是我发现的。

因此,最初的任务是将带有行标识符的列(基本上,序列1 to numRows1 to numRows到任何给定的数据帧,以便可以跟踪行顺序/存在性(例如,当您采样时)。 这可以通过以下方式实现:

sqlContext.textFile(file).
zipWithIndex().
map(case(d, i)=>i.toString + delimiter + d).
map(_.split(delimiter)).
map(s=>Row.fromSeq(s.toSeq))

关于将任何列附加到任何数据框的一般情况:

Spark API 中与此功能“最接近”的是withColumnwithColumnRenamed 根据Scala 文档,前者通过添加列返回一个新的数据帧 在我看来,这有点令人困惑和不完整的定义。 这两个函数都只能对this数据框进行操作,即给定两个数据框df1df2与列col

val df = df1.withColumn("newCol", df1("col") + 1) // -- OK
val df = df1.withColumn("newCol", df2("col") + 1) // -- FAIL

因此,除非您能够设法将现有数据withColumnRenamed的列withColumnRenamed为您需要的形状,否则您不能使用withColumnwithColumnRenamed来附加任意列(独立或其他数据框)。

正如上面所评论的,解决方法可能是使用join - 这会非常混乱,尽管可能 - 将像上面这样的唯一键与zipWithIndex到数据框或列可能会起作用。 虽然效率...

很明显,将一列附加到数据框对于分布式环境来说并不是一个简单的功能,而且可能根本没有非常有效、简洁的方法。 但我认为即使有性能警告,让这个核心功能可用仍然非常重要。

不确定它是否适用于 spark 1.3,但在 spark 1.5 中我使用 withColumn:

import sqlContext.implicits._
import org.apache.spark.sql.functions._


df.withColumn("newName",lit("newValue"))

当我需要使用与数据框的现有列无关的值时,我会使用它

这类似于@NehaM 的答案,但更简单

我从上面的答案中得到了帮助。 但是,如果我们想更改DataFrame并且当前的 API 在Spark 1.6中几乎没有什么不同,我发现它是不完整的。 zipWithIndex()返回一个(Row, Long) Tuple ,其中包含每一行和相应的索引。 我们可以根据需要使用它来创建新的Row

val rdd = df.rdd.zipWithIndex()
             .map(indexedRow => Row.fromSeq(indexedRow._2.toString +: indexedRow._1.toSeq))
val newstructure = StructType(Seq(StructField("Row number", StringType, true)).++(df.schema.fields))
sqlContext.createDataFrame(rdd, newstructure ).show

我希望这会有所帮助。

您可以将row_numberWindow 函数一起使用,如下所示,以获取数据帧中每一行的不同 ID。

df.withColumn("ID", row_number() over Window.orderBy("any column name in the dataframe"))

您也可以使用monotonically_increasing_id

df.withColumn("ID", monotonically_increasing_id())

还有一些其他的方法

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM