我刚刚开始学习scala,并面临一些有关对象RDD操纵的问题。
我遇到以下链接中所述的相同问题
Update the internal state of RDD elements
还有其他方法可以解决上述链接中所述的问题吗?还可以使用数据集或数据框来实现我们想要做的事情吗?
答案 0 :(得分:3)
不可变性是功能编程的关键概念之一。您无法更改RDD
或内部数据,但可以基于旧RDD
中的数据创建新的RDD
。
我从您问题的链接中修改了示例,以显示这种转换通常是什么样子。
//just case class with foo and bar fields that can be empty.
case class Test (foo: Option[Double], bar: Option[Double], someOtherVal: String)
// as you can see this is not actually "update"
// it creates new Test with "updated" foo and bar fields
// NOTE: this logic usually lives outside data object
def updateFooBar(t: Test) = Test(Some(Math.random()), Some(Math.random()),t.someOtherVal)
val testList = Array.fill(5)(Test(None,None,"someString"))
val testRDD = sc.parallelize(testList)
//creates new RDD based on old one by applying updateFooBar to each element.
val newRdd = testRDD.map{ x => updateFooBar(x) }
//or just val newRdd = testRDD.map(updateFooBar)
newRdd.collect().foreach { x=> println(x.foo+"~"+x.bar+"~"+x.someOtherVal) }
您可以像Dataset
一样完全转换RDD
:
val newDs = testRDD.toDS().map( x => updateFooBar(x))
或使用Dataframe
:
import org.apache.spark.sql.functions.typedLit
val newDf = testRDD.toDF()
.withColumn("foo",typedLit(Some(Math.random())))
.withColumn("bar",typedLit(Some(Math.random())))