是否可以在不使用collect
的情况下从数据框中删除第n行,然后转换回dataFrame。我想避免使用collect,因为我有一个大型数据集。
val arr=df.collect().toBuffer
arr.remove(13)
可能以某种方式我可以转换回dataframe.Is有更简单的方法吗? 我试过zipwithIndex,但dataFrame不支持zipwithIndex
value zipWithIndex is not a member of org.apache.spark.sql.DataFrame
答案 0 :(得分:3)
据我所知,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做同样的事情(即创建一个新的列),这意味着你必须考虑不可变/分布式并重写你的部分内容代码,主要是那些不纯粹被认为是数据流转换的部分。
答案 1 :(得分:0)
在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。
谢谢,
查尔斯。