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 中拆分字符串