是否可以在不使用collect
然后转换回dataframe的情况下从数据帧中删除第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
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中的DataFrames就像RDD一样,是一个不可变的数据结构。因此,像创建一个新列或删除一行,或试图通过索引访问DataFrame中的单个元素这样的事情是不可能存在的,因为这种做作违反了Spark的原则。不要忘记,您使用的是分布式数据结构,而不是内存中的随机访问数据结构。
需要明确的是,这并不意味着你不能使用Spark做同样的事情(即创建一个新列),这意味着你必须考虑不可变/分布式并重写代码的部分,大多数部分不是纯粹被认为是数据流上的转换。
在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笔记本。
谢谢,
查尔斯。