Apache spark Spark:查找缺失数字的程序
让我们假设我们有一个这样的数字列表:Apache spark Spark:查找缺失数字的程序,apache-spark,pyspark,Apache Spark,Pyspark,让我们假设我们有一个这样的数字列表: lst = [1,2,4,5,9,10] 我将如何编写Spark程序来查找该列表中缺少的数字。程序应该返回:3,6,7,8 我试着用蓄能器,力道 如果您不太担心有一个最佳解决方案,一种方法是首先广播您拥有的数据,然后并行化包含所有元素的集合,并根据广播的数据进行过滤 差不多 lst = [1,2,4,5,9,10] broadcastVar = sc.broadcast(lst) all_elems = sc.parallelize([i+1 f
lst = [1,2,4,5,9,10]
我将如何编写Spark程序来查找该列表中缺少的数字。程序应该返回:3,6,7,8
我试着用蓄能器,力道 如果您不太担心有一个最佳解决方案,一种方法是首先广播您拥有的数据,然后并行化包含所有元素的集合,并根据广播的数据进行过滤 差不多
lst = [1,2,4,5,9,10]
broadcastVar = sc.broadcast(lst)
all_elems = sc.parallelize([i+1 for i in range(10)])
all_elems.filter(lambda x: x not in broadcastVar.value)
如果您正在寻找只处理少量数据的东西,那么这很好。如果你有很多数据,那么这种方法是不好的,不应该使用
如果需要更好的解决方案,那么我将执行以下操作
这个采样码有很多错误,但它只是概念证明。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.sql.SparkSession;
import org.spark_project.guava.collect.Lists;
import scala.Tuple2;
public class Main {
public static void main(String[] args) {
SparkSession spark = SparkSession.builder().appName("spark-missing-nr").master("local[*]").getOrCreate();
JavaSparkContext sc = new JavaSparkContext(spark.sparkContext());
Integer[] lst = new Integer[] { 1, 2, 4, 5, 9, 10 };
JavaRDD<Integer> lstRDD = sc.parallelize(Arrays.asList(lst));
// Partition the data by whether number is smaller/equal or larger than
// 5
JavaPairRDD<String, Integer> groupableRDD = lstRDD.mapToPair(i -> {
String group = i <= 5 ? "1-5" : "6-10";
return new Tuple2<String, Integer>(group, i);
});
// Group by key
JavaPairRDD<String, Iterable<Integer>> groupedRDD = groupableRDD.groupByKey();
// so now we have [(1-5,[1, 2, 4, 5]), (6-10,[9, 10])]
System.out.println(groupedRDD.collect());
// map where you iterate over range specified by key
JavaRDD<List<Integer>> missingValuesLists = groupedRDD.map(t -> {
Integer from = new Integer(t._1().split("-")[0]);
Integer to = new Integer(t._1().split("-")[1]);
List<Integer> valuesList = Lists.newArrayList(t._2());
List<Integer> missingValues = new ArrayList<Integer>();
// iterate over range specified by key
for (int i = from; i < to + 1; i++) {
if (!valuesList.contains(i)) {
missingValues.add(i);
}
}
return missingValues;
});
// outputs [[3], [6, 7, 8]]
System.out.println(missingValuesLists.collect());
sc.close();
}
}
import java.util.ArrayList;
导入java.util.array;
导入java.util.List;
导入org.apache.spark.api.java.javapairdd;
导入org.apache.spark.api.java.JavaRDD;
导入org.apache.spark.api.java.JavaSparkContext;
导入org.apache.spark.sql.SparkSession;
导入org.spark_project.guava.collect.Lists;
导入scala.Tuple2;
公共班机{
公共静态void main(字符串[]args){
SparkSession spark=SparkSession.builder().appName(“spark缺少nr”).master(“local[*]).getOrCreate();
JavaSparkContext sc=新的JavaSparkContext(spark.sparkContext());
整数[]lst=新整数[]{1,2,4,5,9,10};
javarddlstrdd=sc.parallelize(Arrays.asList(lst));
//按数字是小于/等于还是大于对数据进行分区
// 5
javapairdd groupableRDD=lstRDD.mapToPair(i->{
字符串组=i{
整数from=新整数(t._1().split(“-”[0]);
整数到=新整数(t._1().split(“-”[1]);
List valuesList=Lists.newArrayList(t._2());
List missingValues=new ArrayList();
//迭代键指定的范围
for(int i=from;i
您可以尝试使用sc.range
创建满量程的RDD,然后使用以下功能:
lst=sc.parallelize([1,2,4,5,9,10])
max_value=lst.max()
完整数据=sc.范围(1,最大值)
缺失值=完整数据。减去(lst)
您可以避免调用
max()
如果您事先知道完整列表的大小。可以分享您不起作用的解决方案以及您迄今为止的尝试。对于在计算每一行时依赖于查看其他行的问题,Spark不是最佳选择。Spark是最好的选择,因为您可以在不依赖其他行的情况下处理每一项,因此它可以并行化非常有效。@Daniel,我也知道这一点,但在一次采访中我被要求实现它。我告诉他们使用累加器的解决方案,他们接受了。恐怕我必须用一个大约有10亿个数字的列表来完成。Hi-Ossu54,如果可能的话,你能提供这个的代码示例吗?我用Java添加了一些示例代码,希望没问题。我试过了在Scala,它运行得很好。非常感谢!抱歉Daniel回复晚了(我太忙了).我试过了,但这并不能被认为是最佳解决方案。如果我们要处理数十亿个数字,我们就不能再处理一个如此庞大的数据列表。无论如何,感谢这个解决方案,我喜欢减法部分:)这是最简单的方法。