【Spark篇】---Spark中Action算子

本文详细介绍了Apache Spark中Action算子的功能与用法,包括count、take、foreach、collect等算子的具体实现,并通过示例代码展示了如何在Java和Scala中使用这些算子。

一、前述

Action类算子也是一类算子(函数)叫做行动算子,如foreach,collect,count等。Transformations类算子是延迟执行,Action类算子是触发执行。一个application应用程序(就是我们编写的一个应用程序)中有几个Action类算子执行,就有几个job运行。

二、具体

 原始数据集:

  1、count

返回数据集中的元素数会在结果计算完成后回收到Driver端返回行数

 

package com.spark.spark.actions;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;

/**
 * count
 * 返回结果集中的元素数,会将结果回收到Driver端。
 *
 */
public class Operator_count {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local");
        conf.setAppName("collect");
        JavaSparkContext jsc = new JavaSparkContext(conf);
        JavaRDD<String> lines = jsc.textFile("./words.txt");
        long count = lines.count();
        System.out.println(count);
        jsc.stop();
    }
}

 

 结果:返回行数即元素数

 

2、take(n)

 

       first=take(1) 返回数据集中的第一个元素

 

      返回一个包含数据集n个元素的集合。是一个array有几个partiotion 会有几个job触发

 

package com.spark.spark.actions;

import java.util.Arrays;
import java.util.List;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
/**
 * take
 * 
 * @author root
 *
 */
public class Operator_takeAndFirst {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("take");
        JavaSparkContext jsc = new JavaSparkContext(conf);
        
 
        JavaRDD<String> parallelize = jsc.parallelize(Arrays.asList("a","b","c","d"));
        List<String> take = parallelize.take(2);
        String first = parallelize.first();
        for(String s:take){
            System.out.println(s);
        }
        jsc.stop();
    }
}

结果:

 

3、foreach

      循环遍历数据集中的每个元素,运行相应的逻辑。

4、collect

     将计算结果回收到Driver端。当数据量很大时就不要回收了,会造成oom.

 

     一般在使用过滤算子或者一些能返回少量数据集的算子后

 

package com.spark.spark.actions;

import java.util.List;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;

/**
 * collect 
 * 将计算的结果作为集合拉回到driver端,一般在使用过滤算子或者一些能返回少量数据集的算子后,将结果回收到Driver端打印显示。
 *
 */
public class Operator_collect {
    public static void main(String[] args) {
        /**
         * SparkConf对象中主要设置Spark运行的环境参数。
         * 1.运行模式
         * 2.设置Application name
         * 3.运行的资源需求
         */
        SparkConf conf = new SparkConf();
        conf.setMaster("local");
        conf.setAppName("collect");
        /**
         * JavaSparkContext对象是spark运行的上下文,是通往集群的唯一通道。
         */
        JavaSparkContext jsc = new JavaSparkContext(conf);
        JavaRDD<String> lines = jsc.textFile("./words.txt");
        JavaRDD<String> resultRDD = lines.filter(new Function<String, Boolean>() {

            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            @Override
            public Boolean call(String line) throws Exception {
                return !line.contains("hadoop");
            }
            
        });
        List<String> collect = resultRDD.collect();
        for(String s :collect){
            System.out.println(s);
        }
        
        jsc.stop();
    }
}

结果:

 

  • countByKey

              作用到K,V格式的RDD上,根据Key计数相同Key的数据集元素。也就是个数)

java代码:

package com.spark.spark.actions;

import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaSparkContext;

import scala.Tuple2;
/**
 * countByKey
 * 
 * 作用到K,V格式的RDD上,根据Key计数相同Key的数据集元素。返回一个Map<K,Object>
 * @author root
 *
 */
public class Operator_countByKey {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("countByKey");
        JavaSparkContext sc = new JavaSparkContext(conf);
        JavaPairRDD<Integer, String> parallelizePairs = sc.parallelizePairs(Arrays.asList(
                new Tuple2<Integer,String>(1,"a"),
                new Tuple2<Integer,String>(2,"b"),
                new Tuple2<Integer,String>(3,"c"),
                new Tuple2<Integer,String>(4,"d"),
                new Tuple2<Integer,String>(4,"e")
        ));
        
        Map<Integer, Object> countByKey = parallelizePairs.countByKey();
        for(Entry<Integer,Object>  entry : countByKey.entrySet()){
            System.out.println("key:"+entry.getKey()+"value:"+entry.getValue());
        }
        
        
    }
}

 

结果:

  • countByValue

           根据数据集每个元素相同的内容来计数。返回相同内容的元素对应的条数。

java代码:

 

package com.spark.spark.actions;

import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;

import scala.Tuple2;
/**
 * countByValue
 * 根据数据集每个元素相同的内容来计数。返回相同内容的元素对应的条数。
 * 
 * @author root
 *
 */
public class Operator_countByValue {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("countByKey");
        JavaSparkContext sc = new JavaSparkContext(conf);
        JavaPairRDD<Integer, String> parallelizePairs = sc.parallelizePairs(Arrays.asList(
                new Tuple2<Integer,String>(1,"a"),
                new Tuple2<Integer,String>(2,"b"),
                new Tuple2<Integer,String>(2,"c"),
                new Tuple2<Integer,String>(3,"c"),
                new Tuple2<Integer,String>(4,"d"),
                new Tuple2<Integer,String>(4,"d")
        ));
        
        Map<Tuple2<Integer, String>, Long> countByValue = parallelizePairs.countByValue();
        
        for(Entry<Tuple2<Integer, String>, Long> entry : countByValue.entrySet()){
            System.out.println("key:"+entry.getKey()+",value:"+entry.getValue());
        }
    }
}

 

 scala代码:

 

package com.bjsxt.spark.actions

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
/**
 * countByValue
 * 根据数据集每个元素相同的内容来计数。返回相同内容的元素对应的条数。
 */
object Operator_countByValue {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    conf.setMaster("local").setAppName("countByValue")
    val sc = new SparkContext(conf)
     val rdd1 = sc.makeRDD(List("a","a","b"))
    val rdd2 = rdd1.countByValue()
    rdd2.foreach(println)
    sc.stop()
  }
}

 

 代码结果:

java:

 

scala:

  • reduce

            根据聚合逻辑聚合数据集中的每个元素。(reduce里面需要具体的逻辑,根据里面的逻辑对相同分区的数据进行计算

java代码:

package com.spark.spark.actions;

import java.util.Arrays;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function2;
/**
 * reduce
 * 
 * 根据聚合逻辑聚合数据集中的每个元素。
 * @author root
 *
 */
public class Operator_reduce {
    public static void main(String[] args) {
        SparkConf conf = new SparkConf();
        conf.setMaster("local").setAppName("reduce");
        JavaSparkContext sc = new JavaSparkContext(conf);
        JavaRDD<Integer> parallelize = sc.parallelize(Arrays.asList(1,2,3,4,5));
        
        Integer reduceResult = parallelize.reduce(new Function2<Integer, Integer, Integer>() {
            
            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            @Override
            public Integer call(Integer v1, Integer v2) throws Exception {
                return v1+v2;
            }
        });
        System.out.println(reduceResult);
        sc.stop();
    }
}

scala代码:

 

package com.bjsxt.spark.actions

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
/**
 * reduce
 * 
 * 根据聚合逻辑聚合数据集中的每个元素。
 */
object Operator_reduce {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf()
    conf.setMaster("local").setAppName("reduce")
    
    val sc = new SparkContext(conf)
    val rdd1 = sc.makeRDD(Array(1,2))
    
    val result = rdd1.reduce(_+_)
    
    println(result)
    sc.stop()
  }
}

 

 结果:

java:

scala:

 

 

转载于:https://www.cnblogs.com/LHWorldBlog/p/8401820.html

### Spark算子在Python中的基本用法 #### 什么是Spark算子? Apache Spark 是一种分布式计算框架,支持大规模数据处理。它提供了丰富的操作接口来实现各种数据转换和动作功能。这些操作被称为 **算子 (Operators)** 或者 **Transformation 和 Action**[^1]。 #### 基本概念 - **Transformation**: 转换操作会基于现有的 RDD 创建一个新的 RDD,但不会立即执行。 - **Action**: 动作操作会触发实际的计算过程并返回结果或者将结果保存到外部存储中。 以下是几个常见的 Transformation 和 Action 的例子: --- #### 使用 `map` 进行简单映射 `map` 算子用于对每个元素应用函数,并返回新的 RDD。 ```python from pyspark import SparkContext sc = SparkContext("local", "Map Example") data = ["apple", "banana", "cherry"] rdd = sc.parallelize(data) result_rdd = rdd.map(lambda x: f"{x}_processed") # 对每个字符串附加 "_processed" output = result_rdd.collect() # 收集结果作为列表 print(output) # 输出:['apple_processed', 'banana_processed', 'cherry_processed'] ``` --- #### 使用 `filter` 过滤数据 `filter` 算子可以用来过滤掉不符合条件的数据项。 ```python filtered_rdd = rdd.filter(lambda x: len(x) > 5) # 只保留长度大于5的单词 output_filtered = filtered_rdd.collect() print(output_filtered) # 输出:['banana', 'cherry'] ``` --- #### 使用 `groupByKey` 处理键值对 当需要按 key 组合多个 value 时,可使用 `groupByKey` 算子。此方法适用于 Key-Value 类型的 RDD 数据结构。 ```python kv_data = [("a", 1), ("b", 2), ("a", 3)] kv_rdd = sc.parallelize(kv_data) grouped_rdd = kv_rdd.groupByKey().mapValues(list) # 将相同key对应的value组合成list output_grouped = grouped_rdd.collect() print(output_grouped) # 输出:[('a', [1, 3]), ('b', [2])] ``` 这里需要注意的是,在某些情况下可能更推荐使用 `reduceByKey` 来代替 `groupByKey`,因为后者可能会导致较大的内存占用[^2]。 --- #### 使用 `countByValue` 计数重复值 如果想统计某个集合里各个唯一值的数量,则可以用 `countByValue()` 方法完成这一需求。 ```python repeated_values = ['python', 'python', 'python', 'java', 'java'] values_rdd = sc.parallelize(repeated_values) counts = values_rdd.countByValue() for k, v in counts.items(): print(f"{k}: {v}") # 输出:python: 3\n java: 2 ``` --- #### 结合多种算子构建复杂逻辑 通过链式调用不同类型的算子,能够轻松解决复杂的业务场景问题。 ```python complex_data = [('spark', 2), ('hadoop', 3), ('hive', 4), ('spark', 6)] complex_rdd = sc.parallelize(complex_data) summed_by_key = complex_rdd.reduceByKey(lambda a,b:a+b).sortByKey() final_result = summed_by_key.collect() print(final_result) # 输出:[('hive', 4), ('hadoop', 3), ('spark', 8)] ``` --- ### 总结 上述展示了部分常用的 PySpark 算子及其具体应用场景。每种算子都有其特定用途以及性能特点,合理选用能极大提升程序效率与代码简洁度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值