我需要在巨大的RDD上进行复杂的计算,但为了简单起见,我将问题简化为更简单的方法:
我有一个像这样获得的JavaRDD:
JavaRDD<Student> students = sc.parallelize(
javaFunctions(sc).cassandraTable("test", "school", mapRowTo(Student.class)).collect());
学生课程如下:
public class Student implements Serializable{
Integer id;
Integer classroom;
String name;
Integer mark1;
Integer mark2;
// ... getters and setters
现在,我希望在一次迭代中为每个教室使用stddedv,avg for mark1和mark2列,如果它可能是StatCounter。 我知道如何使用StatCounter,但是通过
JavaRDD<Numeric>
在我的情况下我有
JavaRDD<Student>
有什么想法吗?
由于
答案 0 :(得分:3)
首先,永远不要:
sc.parallelize(someRDD.collect());
这不是一个好主意。像往常一样。
现在:
使用stddedv进行一次迭代,为每个教室使用mark1和mark2列,如果可能的话,使用StatCounter
有可能,但只需将DataFrame
与Cassandra connector一起使用:
import static org.apache.spark.sql.functions.*;
spark
.read
.format("org.apache.spark.sql.cassandra")
.options(Map( "table" -> "school", "keyspace" -> "test"))
.load()
.groupBy("classroom"))
.agg(mean("mark1"), stddev("mark1"), mean("mark2"), stddev("mark2"));
使用统计信息计数器,您可以将JavaPairRDD<Integer,Tuple2<Integer,Integer>>
((class, (mark1, , mark2))
)和combineByKey
转换为Tuple2
StatCounters
。您也可以将Tuple2
替换为mllib.Vector
,并与MultivariateStatisticalSummary