spark java seq_【Spark Java API】Transformation(6)—aggregate、aggregateByKey

aggregate

官方文档描述:

Aggregate the elements of each partition, and then the results for all the partitions,

using given combine functions and a neutral "zero value". This function can return

a different result type, U, than the type of this RDD, T. Thus, we need one operation

for merging a T into an U and one operation for merging two U's, as in scala.TraversableOnce.

Both of these functions are allowed to modify and return their first argument

instead of creating a new U to avoid memory allocation.

函数原型:

def aggregate[U](zeroValue: U)(seqOp: JFunction2[U, T, U], combOp: JFunction2[U, U, U]): U

源码分析:

def aggregate[U: ClassTag](zeroValue: U)(seqOp: (U, T) => U, combOp: (U, U) => U): U = withScope {

// Clone the zero value since we will also be serializing it as part of tasks

var jobResult = Utils.clone(zeroValue, sc.env.serializer.newInstance())

val cleanSeqOp = sc.clean(seqOp)

val cleanCombOp = sc.clean(combOp)

val aggregatePartition = (it: Iterator[T]) => it.aggregate(zeroValue)(cleanSeqOp, cleanCombOp)

val mergeResult = (index: Int, taskResult: U) => jobResult = combOp(jobResult, taskResult)

sc.runJob(this, aggregatePartition, mergeResult)

jobResult

}

**

aggregate函数将每个分区里面的元素进行聚合,然后用combine函数将每个分区的结果和初始值(zeroValue)进行combine操作。这个函数最终返回U的类型不需要和RDD的T中元素类型一致。 这样,我们需要一个函数将T中元素合并到U中,另一个函数将两个U进行合并。其中,参数1是初值元素;参数2是seq函数是与初值进行比较;参数3是comb函数是进行合并 。

注意:如果没有指定分区,aggregate是计算每个分区的,空值则用初始值替换

**

实例:

List data = Arrays.asList(5, 1, 1, 4, 4, 2, 2);

JavaRDD javaRDD = javaSparkContext.parallelize(data,3);

Integer aggregateValue = javaRDD.aggregate(3, new Function2() {

@Override

public Integer call(Integer v1, Integer v2) throws Exception {

System.out.println("seq~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + v1 + "," + v2);

return Math.max(v1, v2);

}

}, new Function2() {

int i = 0;

@Override

public Integer call(Integer v1, Integer v2) throws Exception {

System.out.println("comb~~~~~~~~~i~~~~~~~~~~~~~~~~~~~"+i++);

System.out.println("comb~~~~~~~~~v1~~~~~~~~~~~~~~~~~~~" + v1);

System.out.println("comb~~~~~~~~~v2~~~~~~~~~~~~~~~~~~~" + v2);

return v1 + v2;

}

});

System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"+aggregateValue);

aggregateByKey

官方文档描述:

Aggregate the values of each key, using given combine functions and a neutral "zero value".

This function can return a different result type, U, than the type of the values in this RDD,V.

Thus, we need one operation for merging a V into a U and one operation for merging

two U's,as in scala.TraversableOnce. The former operation is used for merging values

within a partition, and the latter is used for merging values between partitions.

To avoid memory allocation, both of these functions are allowed to modify and return

their first argument instead of creating a new U.

函数原型:

def aggregateByKey[U](zeroValue: U, partitioner: Partitioner, seqFunc: JFunction2[U, V, U],

combFunc: JFunction2[U, U, U]): JavaPairRDD[K, U]

def aggregateByKey[U](zeroValue: U, numPartitions: Int, seqFunc: JFunction2[U, V, U],

combFunc: JFunction2[U, U, U]): JavaPairRDD[K, U]

def aggregateByKey[U](zeroValue: U, seqFunc: JFunction2[U, V, U], combFunc: JFunction2[U, U, U]): JavaPairRDD[K, U]

源码分析:

def aggregateByKey[U: ClassTag](zeroValue: U, partitioner: Partitioner)(seqOp: (U, V) => U,

combOp: (U, U) => U): RDD[(K, U)] = self.withScope {

// Serialize the zero value to a byte array so that we can get a new clone of it on each key

val zeroBuffer = SparkEnv.get.serializer.newInstance().serialize(zeroValue)

val zeroArray = new Array[Byte](zeroBuffer.limit)

zeroBuffer.get(zeroArray)

lazy val cachedSerializer = SparkEnv.get.serializer.newInstance()

val createZero = () => cachedSerializer.deserialize[U](ByteBuffer.wrap(zeroArray))

// We will clean the combiner closure later in `combineByKey`

val cleanedSeqOp = self.context.clean(seqOp)

combineByKey[U]((v: V) => cleanedSeqOp(createZero(), v), cleanedSeqOp, combOp, partitioner)

}

**

aggregateByKey函数对PairRDD中相同Key的值进行聚合操作,在聚合过程中同样使用了一个中立的初始值。和aggregate函数类似,aggregateByKey返回值的类型不需要和RDD中value的类型一致。因为aggregateByKey是对相同Key中的值进行聚合操作,所以aggregateByKey函数最终返回的类型还是Pair RDD,对应的结果是Key和聚合好的值;而aggregate函数直接是返回非RDD的结果,这点需要注意。在实现过程中,定义了三个aggregateByKey函数原型,但最终调用的aggregateByKey函数都一致。其中,参数zeroValue代表做比较的初始值;参数partitioner代表分区函数;参数seq代表与初始值比较的函数;参数comb是进行合并的方法。

**

实例:

//将这个测试程序拿文字做一下描述就是:在data数据集中,按key将value进行分组合并,

//合并时在seq函数与指定的初始值进行比较,保留大的值;然后在comb中来处理合并的方式。

List data = Arrays.asList(5, 1, 1, 4, 4, 2, 2);

int numPartitions = 4;

JavaRDD javaRDD = javaSparkContext.parallelize(data);

final Random random = new Random(100);

JavaPairRDD javaPairRDD = javaRDD.mapToPair(new PairFunction() {

@Override

public Tuple2 call(Integer integer) throws Exception {

return new Tuple2(integer,random.nextInt(10));

}

});

System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"+javaPairRDD.collect());

JavaPairRDD aggregateByKeyRDD = javaPairRDD.aggregateByKey(3,numPartitions, new Function2() {

@Override

public Integer call(Integer v1, Integer v2) throws Exception {

System.out.println("seq~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + v1 + "," + v2);

return Math.max(v1, v2);

}

}, new Function2() {

int i = 0;

@Override

public Integer call(Integer v1, Integer v2) throws Exception {

System.out.println("comb~~~~~~~~~i~~~~~~~~~~~~~~~~~~~" + i++);

System.out.println("comb~~~~~~~~~v1~~~~~~~~~~~~~~~~~~~" + v1);

System.out.println("comb~~~~~~~~~v2~~~~~~~~~~~~~~~~~~~" + v2);

return v1 + v2;

}

});

System.out.println("aggregateByKeyRDD.partitions().size()~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"+aggregateByKeyRDD.partitions().size());

System.out.println("aggregateByKeyRDD~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"+aggregateByKeyRDD.collect());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ethercat injection_seq_rt和injection_seq_fsm是与车辆发动系统相关的两个技术术语。 EtherCAT(以太网控制自动化技术)是一种高性能实时以太网技术,用于工业自动化中的实时控制和数据交换。其中的injection_seq_rt是指以太网注入序列实时模块,通常用于汽车发动机控制系统中的稳态控制。 另一方面,汽车发动机控制需要的很多功能都需要状态机(FSM)来实现。FSM是一种数学模型,用于描述系统的状况和它们之间的转移。因此,injection_seq_fsm就是描述汽车发动机控制系统中燃油注入状态机的模块。 总的来说,ethercat injection_seq_rt和injection_seq_fsm是两个关键技术,在汽车发动机控制系统中有着重要的作用。它们能为整个系统的运行提供稳定性和高效性,使得汽车在行驶过程中更加安全和可靠。同时,它们的应用也能够缩短汽车开发周期和提高生产效率。 ### 回答2: ethercat injection_seq_rt injection_seq_fsm是指在以太网CAT网络中,实时传输控制器(RT)和状态机(FSM)使用注入序列(injection_seq)来确定数据的传输顺序。 以太网CAT网络是一种高性能、实时性强的工业以太网,广泛应用于现代工业自动化控制系统中。传输控制器(RT)是其中的重要组成部分,它负责控制数据的传输和处理。而状态机(FSM)则是用来管理和维护实时性。 在以太网CAT网络中,注入序列(injection_seq)是用来确定数据包的发送顺序的。通过注入序列的使用,可以使数据包按照正确的顺序进行传输,并确保实时性的同时保证数据的准确性,以满足现代工业自动化控制系统对数据传输要求的严格要求。 综上所述,ethercat injection_seq_rt injection_seq_fsm是以太网CAT网络中实时传输控制器(RT)和状态机(FSM)使用注入序列(injection_seq)来确定数据的传输顺序的技术术语。它确保了数据包的实时性、正确性和可靠性,并广泛应用于现代工业自动化控制系统之中。 ### 回答3: EtherCAT是一种高性能的实时以太网通信协议,在工业控制领域得到广泛应用。其中,injection_seq_rt和injection_seq_fsm是EtherCAT通信中的两个重要概念。 injection_seq_rt是EtherCAT通信协议中的实时数据传输机制,用于实现对实时数据的高效传输。它是通过将数据分割为若干个包进行传输,并在接收端进行实时重构来实现的。 而injection_seq_fsm则是EtherCAT通信协议中的有限状态机,用于控制数据包的发送和接收。它可以根据实时网络负载和数据缓存状态,动态调整数据发送和接收的速率,从而保证数据传输的稳定性和实时性。 总的来说,EtherCAT通信协议的实时性和高效性得益于injection_seq_rt和injection_seq_fsm这两个重要机制的支持,它们共同构成了EtherCAT的核心技术。在工业控制领域,EtherCAT通信协议已经成为了众多领域专业人士和企业所信赖的通信协议,正在为工业自动化领域的发展做出日益重要的贡献。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值