我想遍历一个字符串的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;
}
答案 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))
}