Spark:在Scala中使用mapPartition

Spark:在Scala中使用mapPartition,scala,apache-spark,Scala,Apache Spark,假设我有以下数据帧: var randomData = Seq(("a",8),("h",5),("f",3),("a",2),("b",8),("c",3) val df = sc.parallelize(randomData,2).toDF() 我有一个函数,它将作为mapPartition的输入: def trialIterator(row:Iterator[(String,Int)]): Iterator[(String,Int)] = row.toArray.tail.toI

假设我有以下数据帧:

var randomData = Seq(("a",8),("h",5),("f",3),("a",2),("b",8),("c",3)
val df = sc.parallelize(randomData,2).toDF()
我有一个函数,它将作为
mapPartition
的输入:

def trialIterator(row:Iterator[(String,Int)]): Iterator[(String,Int)] =
    row.toArray.tail.toIterator
并使用地图分区:

df.mapPartition(trialIterator)
我收到以下错误消息:

类型不匹配,应为(迭代器[Row])=>Iterator[NotInferedR],实际为:迭代器[(字符串,Int)=>Iterator[(字符串,Int)]


我可以理解,这是由于我的函数的输入、输出类型造成的,但如何解决这个问题呢?

您需要类型
迭代器[(字符串,Int)]
,而您应该需要
迭代器[行]

def trialIterator(row:Iterator[Row]): Iterator[(String,Int)] = {
    row.next()
    row //seems to do the same thing w/o all the conversions
}

如果您想获得强类型输入,不要使用
Dataset[Row]
DataFrame
)而是
Dataset[t]
,其中
t
在这个特定场景中是
(String,Int)
。也不要转换为
数组
,也不要在不知道分区是否为空的情况下盲目调用
tail

def trialIterator(iter: Iterator[(String, Int)]) = iter.drop(1)

randomData
  .toDS // org.apache.spark.sql.Dataset[(String, Int)]
  .mapPartitions(trialIterator _)


谢谢你的回答。这里的功能只是为了说明我的问题。不是我想要使用的那个。为什么我不应该使用DataFrAMs?因为对于实际应用<代码>数据文件< /COD>只是一个<代码>数据集[SEQ[ON] ] /代码>,所以你可以简单地认为它是非类型化的/不是类型安全的。
randomData.toDF // org.apache.spark.sql.Dataset[Row] 
  .as[(String, Int)] // org.apache.spark.sql.Dataset[(String, Int)]
  .mapPartitions(trialIterator _)