Spark Scala Dataframe:删除第 n 条记录

Posted

技术标签:

【中文标题】Spark Scala Dataframe:删除第 n 条记录【英文标题】:Spark Scala Dataframe: Delete nth Record 【发布时间】:2016-04-05 04:46:13 【问题描述】:

是否可以在不使用collect 的情况下从数据帧中删除第 n 行,然后再转换回数据帧。我想避免使用 collect,因为我有一个大型数据集。

val arr=df.collect().toBuffer
arr.remove(13)

可能我可以以某种方式转换回数据框。有更简单的方法吗? 我试过 zipwithIndex 但dataFrame不支持 zipwithIndex

value zipWithIndex is not a member of org.apache.spark.sql.DataFrame

【问题讨论】:

【参考方案1】:

据我所知,DataFrame 不支持此功能,您需要使用 RDD API。之后您可以立即转换回 DataFrame。

请注意,这与使用 collect 将所有数据复制到您的驱动程序非常不同。

val filteredRdd = input.rdd.zipWithIndex().collect  case (r, i) if i != 13 => r 
val newDf = sqlContext.createDataFrame(filteredRdd, input.schema)

(这里使用的collect 不是将数据收集到驱动程序的那个,它应用一个部分函数来在一次调用中进行过滤和映射)。

免责声明:请记住,Spark 中的 DataFrame 类似于 RDD,因为它们是不可变的数据结构。因此,诸如创建新列或删除行,或尝试通过索引访问 DataFrame 中的单个元素之类的事情是不存在的,因为这种做作违背了 Spark 的原则。不要忘记您使用的是分布式数据结构,而不是内存中的随机访问数据结构。

明确地说,这并不意味着您不能使用 Spark 做同样的事情(即创建一个新列),这意味着您必须考虑不可变/分布式并重写您的部分内容代码,主要是那些不纯粹被视为对数据流进行转换的部分。

【讨论】:

【参考方案2】:

在 Spark 术语中,我会说转换 RDD 比转换它更好。 这是一个建议使用过滤器方法更有效地执行此操作的示例。 对于这个例子,你肯定需要索引列。

import org.apache.spark.sql._

val list = Seq(("one", 1), ("two", 2), ("three", 3),("four", 4),("five", 5))
val sqlContext = new SQLContext(sc)

val numdf = sqlContext.createDataFrame(list)
numdf.printSchema()

root
 |-- _1: string (nullable = true)
 |-- _2: integer (nullable = false)

newdf = numdf.filter(numdf("_2")<2 or numdf("_2")>2).show()

这是我的#bluemix notebook。

谢谢,

查尔斯。

【讨论】:

以上是关于Spark Scala Dataframe:删除第 n 条记录的主要内容,如果未能解决你的问题,请参考以下文章

在 Spark 上使用 Scala 在 Dataframe 中拆分字符串

Spark SCALA - 连接两个数据帧,其中一个数据帧中的连接值位于第二个数据帧中的两个字段之间

spark 统计Dataframe 列的中空值比例

林子雨spark scala版编程小结

Scala/Spark - 如何获取所有子数组的第一个元素

字符串列包含通过 spark scala 精确匹配的单词