Apache spark Can';我不了解aggregateByKey和combineByKey的工作原理

Apache spark Can';我不了解aggregateByKey和combineByKey的工作原理,apache-spark,pyspark,Apache Spark,Pyspark,我是学习ApacheSpark的初学者。目前,我正在尝试使用Python学习各种聚合 为了给我所面临的问题提供一些背景知识,我发现很难理解aggregateByKey函数按“状态”计算订单数量的工作原理 下面是我正在处理的代码和一些示例输出 ordersRDD = sc.textFile("/user/cloudera/sqoop_import/orders") for i in ordersRDD.take(10): print(i) 输出: 12013-07-25 00:00:00.011

我是学习ApacheSpark的初学者。目前,我正在尝试使用Python学习各种聚合

为了给我所面临的问题提供一些背景知识,我发现很难理解aggregateByKey函数按“状态”计算订单数量的工作原理

下面是我正在处理的代码和一些示例输出

ordersRDD = sc.textFile("/user/cloudera/sqoop_import/orders")
for i in ordersRDD.take(10): print(i)
输出:
12013-07-25 00:00:00.011599,关闭
22013-07-25 00:00:00.0256,待付款
32013-07-25 00:00:00.012111,完成
42013-07-25 00:00:00.08827,关闭
52013-07-25 00:00:00.011318,完成
62013-07-25 00:00:00.07130,完成
72013-07-25 00:00:00.04530,完成
82013-07-25 00:00:00.02911,处理
92013-07-25 00:00:00.05657,待付款
102013-07-25 00:00:00.05648,待付款

ordersMap = ordersRDD.map(lambda x: (x.split(",")[3], x))
输出:
(u'CLOSED',u'12013-07-25 00:00:00.011599,CLOSED')
(u'PENDING_PAYMENT',u'22013-07-25 00:00:00.0256,PENDING_PAYMENT')
(u'COMPLETE',u'32013-07-25 00:00:00.012111,COMPLETE')
(u'CLOSED',u'42013-07-25 00:00:00.08827,CLOSED')
(u'COMPLETE',u'52013-07-25 00:00:00.011318,COMPLETE')
(u'COMPLETE',u'62013-07-25 00:00:00.07130,COMPLETE')
(u'COMPLETE',u'72013-07-25 00:00:00.04530,COMPLETE')
(u'PROCESSING',u'82013-07-25 00:00:00.02911,PROCESSING')
(u'PENDING_PAYMENT',u'92013-07-25 00:00:00.05657,PENDING_PAYMENT')
(u'102013-07-25 00:00:00.05648“待付款”,u'102013-07-25 00:00.05648,“待付款”)

最终输出:
(u‘涉嫌欺诈’,1558)
(1428年取消)
(u'COMPLETE',22899)
(15030年,待付款)
(u'PENDING',7610)
(u'CLOSED',7556)
(u'ON_HOLD',3798)
(u'PROCESSING',8275)
(u‘付款审核’,729)

我难以理解的问题是:
1.为什么aggregateByKey函数将2个lambda函数作为参数?
2.将第一个lambda函数的功能可视化?
3.将第二个lambda函数的功能可视化

如果您能用一些简单的方框图来解释上述问题以及aggregateByKey的工作原理,那将非常有帮助?也许是一些中间计算

谢谢你的帮助

谢谢,

Shiv

Spark RDD被划分为多个分区,因此当您对所有数据执行聚合函数时,您将首先聚合每个分区内的数据(分区只是数据的一个子分区)。然后,您需要告诉Spark如何聚合分区

第一个lambda函数告诉Spark在遇到新值时如何更改运行计数(累加器)。由于您正在计数,因此只需将1添加到累加器中。在一个切片中,如果运行计数当前为4,并且添加了另一个值,则运行计数应为
4+1=5
。第一个lambda函数是:

lambda acc,val:acc+1
第二个lambda函数告诉Spark如何将一个数据片段的运行计数与另一个数据片段的运行计数相结合。如果一个切片的计数为5,第二个切片的计数为7,则组合计数为
5+7=12
。因此,您的第二个函数最好编写为:

lambda acc1、acc2:acc1+acc2

剩下的唯一微妙之处是,一切都是在“按键”的基础上完成的。累加器(计数)根据钥匙的不同而不同。

@JustinPihony感谢您为我指出这一点。非常有用谢谢你的回答!现在这是完全有道理的。我确实对你的答案投了赞成票,但我的声誉不高,不足以公开发表。谢谢你的帮助!
ordersByStatus = ordersMap.aggregateByKey(0, lambda acc, val: acc + 1, lambda acc,val: acc + val)
for i in ordersByStatus.take(10): print(i)