按行迭代Java RDD

时间:2015-08-05 14:04:46

标签: java apache-spark rdd

我想遍历一个字符串的RDD并为每个字符串“做一些事情”。输出应为double[][]。这是一个带有for循环的例子。我知道我需要使用(我认为)Java RDD的foreach函数。但是,我不知道如何理解语法。文档不是特别有用。我没有Java 8。

以下是我想要使用常规for循环时我想做的一个示例。

public class PCA {

    public static void main(String[] args) {
        SparkConf conf = new SparkConf().setAppName("PCA Example");
        SparkContext sc = new SparkContext(conf);

        RDD<String> data = sc.textFile("my/directory/my/dataset.txt", 0);

        // here is the "type" of code I would like to execute
        // 30 because I have 30 variables
        double[][] vals = new double[data.count()][30];

        double[] temp;
        for (int i = 0; i < data.count(); i++) {
            temp = splitStringtoDoubles(data[i]);
            vals[i] = temp;
        }
    }

    private static double[] splitStringtoDoubles(String s) {
        String[] splitVals = s.split("\\t");
        Double[] vals = new Double[splitVals.length];
        for (int i = 0; i < splitVals.length; i++) {
            vals[i] = Double.parseDouble(splitVals[i]);
        }
    }

}

我理解foreach似乎需要一个具有void返回类型的函数。不知道如何使用它。这是我到目前为止所尝试的(显然语法错误):

    double[][] matrix = new double[data.count()][30];
    foreach(String s : data) {
        String[] splitvals = s.split("\\t");
        double[] vals = Double.parseDouble(splitvals);
        matrix[s] = vals; 
    }

2 个答案:

答案 0 :(得分:4)

正如 mattinbits 在评论中所说,您需要<dependency> <groupId>org.wildfly</groupId> <artifactId>wildfly-ejb-client-bom</artifactId> <type>pom</type> <version>9.0.1.Final</version> </dependency> <dependency> <groupId>org.wildfly</groupId> <artifactId>wildfly-jms-client-bom</artifactId> <type>pom</type> <version>9.0.1.Final</version> </dependency> 而不是map,因为您想要返回值。 foreach基本上用于转换数据:对于RDD的每一行,您执行一个操作并为每一行返回一个值。你需要的是这样的:

map

为了让您了解Spark的工作原理,您可以对RDD执行操作或转换。例如,我们在这里使用import org.apache.spark.api.java.function.Function; ... SparkConf conf = new SparkConf().setAppName("PCA Example"); SparkContext sc = new SparkContext(conf); JavaRDD<String> data = sc.textFile("clean-sl-mix-with-labels.txt",0).toJavaRDD(); JavaRDD<double[]> whatYouWantRdd = data.map(new Function<String, double[]>() { @Override public double[] call(String row) throws Exception { return splitStringtoDoubles(row); } private double[] splitStringtoDoubles(String s) { String[] splitVals = s.split("\\t"); Double[] vals = new Double[splitVals.length]; for(int i=0; i < splitVals.length; i++) { vals[i] = Double.parseDouble(splitVals[i]); } return vals; } }); List<double[]> whatYouWant = whatYouWantRdd.collect(); 函数转换RDD。您需要自己创建此函数,这次使用匿名map强制您覆盖方法org.apache.spark.api.java.function.Function,您将收到一行RDD并返回一个值。

答案 1 :(得分:4)

仅仅因为比较Java与Scala API for Spark的冗长有趣,这里是一个Scala版本:

import org.apache.spark.{SparkContext, SparkConf}

class example extends App {
  val conf = new SparkConf().setMaster("local").setAppName("Spark example")
  val sc = new SparkContext(conf)

  val inputData = List(
    "1.2\t2.7\t3.8",
    "4.3\t5.1\t6.3"
  )

  val inputRDD = sc.parallelize(inputData)
  val arrayOfDoubleRDD = inputRDD.map(_.split("\t").map(_.toDouble))
}