如何删除数据帧 Scala/sSark 中的前几行?

men*_*gwu 5 apache-spark apache-spark-sql

我有一个 DataFrame,我想删除第一行和第二行。我应该怎么办?

这是我的输入:

+-----+
|value|
+-----+
|    1|
|    4|
|    3|
|    5|
|    4|
|   18|
-------
Run Code Online (Sandbox Code Playgroud)

这是例外的结果:

+-----+
|value|
+-----+
|    3|
|    5|
|    4|
|   18|
-------
Run Code Online (Sandbox Code Playgroud)

Rap*_*oth 5

在我看来,如果您无法定义数据帧的顺序,那么谈论第一条或第二条记录是没有意义的。该语句结果的记录顺序show是“任意的”,并且取决于数据的分区。

假设您有一列可以对记录进行排序,则可以使用窗口函数。从这个数据框开始:

+----+-----+
|year|value|
+----+-----+
|2007|    1|
|2008|    4|
|2009|    3|
|2010|    5|
|2011|    4|
|2012|   18|
+----+-----+ 
Run Code Online (Sandbox Code Playgroud)

你可以做

import org.apache.spark.sql.expressions.Window

df
.withColumn("rn",row_number().over(Window.orderBy($"year")))
.where($"rn">2).drop($"rn")
.show
Run Code Online (Sandbox Code Playgroud)


Sha*_*ala 0

简单易行的方法是为每一行分配一个id并对其进行过滤

val df = Seq(1,2,3,5,4,18).toDF("value")

df.withColumn("id", monotonically_increasing_id()).filter($"id" > 1).drop("id")
Run Code Online (Sandbox Code Playgroud)

编辑:由于monotonically_increasing_id()不连续授予者您可以使用zipWithUniqueId如下

val rows = df.rdd.zipWithUniqueId().map {
  case (row, id) => Row.fromSeq(row.toSeq :+ id)
}

val df1 = spark.createDataFrame(rows, StructType(df.schema.fields :+ StructField("id", LongType, false)))

df1.filter($"id" > 1).drop("id")
Run Code Online (Sandbox Code Playgroud)

输出:

+-----+
|value|
+-----+
|    3|
|    5|
|    4|
|   18|
+-----+
Run Code Online (Sandbox Code Playgroud)

这也将帮助您删除数据框中的第 n 行。

希望这可以帮助!

  • “monotonically_increasing_id()”的一个问题是它不能保证连续的数字。从源代码中的注释来看:“生成的ID保证单调递增且唯一,但不连续。” (5认同)