Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark Spark:查找缺失数字的程序_Apache Spark_Pyspark - Fatal编程技术网

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)
如果您正在寻找只处理少量数据的东西,那么这很好。如果你有很多数据,那么这种方法是不好的,不应该使用

如果需要更好的解决方案,那么我将执行以下操作

  • 基本上是对数据进行分区,使用RDD可以生成一个输出(分区、编号)的映射。您可以编写一个小函数来获取每个数字的分区号。例如,如果你在这个地图后面有两个执行者,你会有类似[(1-5,1),(1-5,2),(1-5,4),(1-5,5),(6-10,9),(6-10,10)]
  • 按键分组,现在我们有[(1-5,[1,2,4,5]),(6-10,[9,10])]
  • 映射在键指定的范围内进行迭代的位置,与值中的元素进行比较,并返回不存在的元素列表
  • 然后,您可以编写结果或收集结果,或对其执行任何操作。值得注意的是,例如,如果我使用了5个执行器,那么键应该是1-2,3-4,5-6,7-8,9-10,键7-8就不会有任何元素。为了避免这种情况,一种方法是在按键分组之前将rdd与[(1-2,-1),(3-4,-1),(5-6,-1),(7-8,-1),(9-10,-1)]结合起来。如果您有大量数据,那么与整个作业相比,由此增加的开销非常小

    这个采样码有很多错误,但它只是概念证明。

    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回复晚了(我太忙了).我试过了,但这并不能被认为是最佳解决方案。如果我们要处理数十亿个数字,我们就不能再处理一个如此庞大的数据列表。无论如何,感谢这个解决方案,我喜欢减法部分:)这是最简单的方法。