在Spark/Scala中为每个GroupBy运行自己的函数
必须在Spark/Scala中处理行,请帮助 我有以下数据帧DF1:在Spark/Scala中为每个GroupBy运行自己的函数,scala,apache-spark,hadoop,apache-spark-sql,hdfs,Scala,Apache Spark,Hadoop,Apache Spark Sql,Hdfs,必须在Spark/Scala中处理行,请帮助 我有以下数据帧DF1: ACC_SECURITY|ACCOUNT_NO|COSTCENTER| BU| MPU|LONG_IND|SHORT_IND|SECURITY_ID|QUANTITY|POS_NEG_QUANTITY|PROCESSED|ALLOC_QUANTITY|NET_QUANTITY| +-------------+----------+----------+------+------+--------+---------+
ACC_SECURITY|ACCOUNT_NO|COSTCENTER| BU| MPU|LONG_IND|SHORT_IND|SECURITY_ID|QUANTITY|POS_NEG_QUANTITY|PROCESSED|ALLOC_QUANTITY|NET_QUANTITY|
+-------------+----------+----------+------+------+--------+---------+-----------+--------+----------------+---------+--------------+------------+
|3FA34789290X2| 3FA34789| 0800TS|BOXXBU|BOXXMP| 0101| 5279| 290X2| 18063| P| | 0| 0|
|3FA34782290X2| 3FA34782| 0800TS|BOXXBU|BOXXMP| 0102| 5322| 290X2| -863| N| | 0| 0|
|3FA34789290X2| 3FA34789| 0800TS|BOXXBU|BOXXMP| 0101| 5279| 290X2| -108926| N| | 0| 0|
|9211530135G71| 92115301| 08036C|BOXXBU|BOXXMP| 0154| 8380| 35G71| 8003| P| | 0| 0|
|9211530235G71| 92115302| 08036C|BOXXBU|BOXXMP| 0144| 8382| 35G71| -2883| N| | 0| 0|
数据帧DF2:
|ENTITY|MATRIX|PRIORITY|LONG_CODE|SHORT_CODE|
+------+------+--------+---------+----------+
300| 00| 16600| 0101| 5322|
300| 00| 19900| 0101| 5279|
300| 00| 298300| 0102| 5279|
300| 00| 17800| 0154| 8382|
300| 00| 505900| 0233| 5279|
我想在上面的数据帧上按安全性进行分组\u ID…然后将得到以下2个组:
ACC_SECURITY|ACCOUNT_NO|COSTCENTER| BU| MPU|LONG_IND|SHORT_IND|SECURITY_ID|QUANTITY|POS_NEG_QUANTITY|PROCESSED|ALLOC_QUANTITY|NET_QUANTITY|
+-------------+----------+----------+------+------+--------+---------+-----------+--------+----------------+---------+--------------+------------+
|3FA34789290X2| 3FA34789| 0800TS|BOXXBU|BOXXMP| 0101| 5279| 290X2| 18063| P| | 0| 0|
|3FA34782290X2| 3FA34782| 0800TS|BOXXBU|BOXXMP| 0102| 5322| 290X2| -863| N| | 0| 0|
|3FA34789290X2| 3FA34789| 0800TS|BOXXBU|BOXXMP| 0101| 5279| 290X2| -108926| N| | 0| 0|
ACC_SECURITY|ACCOUNT_NO|COSTCENTER| BU| MPU|LONG_IND|SHORT_IND|SECURITY_ID|QUANTITY|POS_NEG_QUANTITY|PROCESSED|ALLOC_QUANTITY|NET_QUANTITY|
+-------------+----------+----------+------+------+--------+---------+-----------+--------+----------------+---------+--------------+------------+
|9211530135G71| 92115301| 08036C|BOXXBU|BOXXMP| 0154| 8380| 35G71| 8003| P| | 0| 0|
|9211530235G71| 92115302| 08036C|BOXXBU|BOXXMP| 0144| 8382| 35G71| -2883| N| | 0| 0|
+-------------+----------+----------+------+------+--------+---------+-----------+--------+----------------+---------+--------------+------------+
然后在每组中,我想
-从数量为正的行获取长索引,从数量为负的行获取短索引
并从优先级数据帧DF2中查找优先级,按优先级的升序排序
仅计算第一组,我得到以下数据:
|LONG_CODE|SHORT_CODE|PRIORITY|
+---------+----------+--------+|
0101| 5322| 16600|
0101| 5279| 19900|
0102| 5279| 298300|
然后根据上述优先级添加数量来处理DF1。。。这里我们进行2次迭代
所以Row1.Quantity和Row2.Quantity相加,根据结果是正数还是负数更新其他列
-ALLOC_数量-中和了多少数量(这里是18063-863,所以863是中和的)
-净数量-第二次迭代剩余处理的数量(此处剩余18063-863=17200)
-已处理-如果净数量为零,则输入“p”。因此,这里仅处理了第二行,因此仅处理=p
迭代1:处理第1行和第2行。数量=18063+(-863)=17200(正数保留第1行的其他列)
迭代2:处理第1行和第3行。数量=17200+(-108926)=-91726(负数保留第3行的其他列)
这里第1行。已处理的变为p,第3行。已处理的变为p,只是因为该组已完成3行的所有处理
我尝试了下面的方法,但无法破解,请帮助创建一个函数来对每个组中的行执行上述迭代。可能使用GroupByKey和mapgroups
case class AllocOneProcess(ACC_SECURITY: String, ACCOUNT_NO: String, COSTCENTER: String, BU: String, MPU: String, LONG_IND: String, SHORT_IND: String, SECURITY_ID: String, QUANTITY: String, POS_NEG_QUANTITY: String, PROCESSED: String, ALLOC_QUANTITY: Integer, NET_QUANTITY: Integer)
val toBeProcessedAllocOneDF2 = toBeProcessedAllocOneDF.as[AllocOneProcess]
val toBeProcessedAllocOneDF3 = toBeProcessedAllocOneDF.toDF()
prioritymatrixDF.show()
//toBeProcessedAllocOneDF
val x = toBeProcessedAllocOneDF2
.groupByKey(_.SECURITY_ID)
.mapGroups{
case (nameKey, df) => {
allocOneProcess(df,)
}
}
这个问题不清楚,请检查它,以便我们可以尝试提供帮助!我必须按DF1中的安全ID分组,获取长索引和短索引列表,并在DF2中搜索。然后根据长索引组合的优先级,从不同行中选择短索引(从DF1.ROW1中选择长索引,从DF2.ROW2中选择短索引构成优先级),通过对数量求和处理DF1(仅当数量为加号和减号时)在相反的标识中。因此,假设DF1.ROW1.LONG_IND和DF1.ROW2.SHORT_IND的优先级高于DF1.ROW1.LONG_IND和DF1.ROW3.SHORT_IND,然后添加DF1.ROW1.QUANTITY和DF1.ROW2.QUANTITY,得到18063-863=17200。然后我又有一行DF1.ROW3,依此类推,所以在处理DF1.ROW1和DF1.ROW2之后,我得到17200,这是正的,所以我创建一个新行,而不是这两行,其中所有列数据都来自DF1.ROW1,除了数量是总和=17200。我们在这一新行中取第1行中的其他列,因为最终数量为正数。现在取这一新行并使用DF1.ROW3。因为新行和第3行的数量相反(17200和-108926),一个为正,一个为负,我们将数量相加,得到17200-108926=-91726。这一新行将包含来自DF1.ROW3的所有数据,数量为-91726。我们从第3行获取其他列,因为最终数量为负。因此,在处理第一个安全性为_Id 290X2的组结束时,我们将有3行变为1行,其中包含第3行和Qua的所有详细信息实体为-91726。在高级别上,我们需要这样做。在DF1中,根据安全ID分组,从正数行中提取长索引,从负数行中提取短索引,在DF2中检查此组合的优先级,然后处理DF1。在处理DF1中的每个安全性时,如果我们有相反的标识数量,我们将得到一行。如果没有相反的标识数量,则如果没有,那么我们就让行保持不变。
ACC_SECURITY|ACCOUNT_NO|COSTCENTER| BU| MPU|LONG_IND|SHORT_IND|SECURITY_ID|QUANTITY|POS_NEG_QUANTITY|PROCESSED|ALLOC_QUANTITY|NET_QUANTITY|
+-------------+----------+----------+------+------+--------+---------+-----------+--------+----------------+---------+--------------+------------+
3FA34789290X2| 3FA34789| 0800TS|BOXXBU|BOXXMP| 0101| 5279| 290X2| 18063| P| P | 863| 17200|
3FA34782290X2| 3FA34782| 0800TS|BOXXBU|BOXXMP| 0102| 5322| 290X2| -863| N| P | 0| 0|
3FA34789290X2| 3FA34789| 0800TS|BOXXBU|BOXXMP| 0101| 5279| 290X2| -108926| N| P | 0| 0|
case class AllocOneProcess(ACC_SECURITY: String, ACCOUNT_NO: String, COSTCENTER: String, BU: String, MPU: String, LONG_IND: String, SHORT_IND: String, SECURITY_ID: String, QUANTITY: String, POS_NEG_QUANTITY: String, PROCESSED: String, ALLOC_QUANTITY: Integer, NET_QUANTITY: Integer)
val toBeProcessedAllocOneDF2 = toBeProcessedAllocOneDF.as[AllocOneProcess]
val toBeProcessedAllocOneDF3 = toBeProcessedAllocOneDF.toDF()
prioritymatrixDF.show()
//toBeProcessedAllocOneDF
val x = toBeProcessedAllocOneDF2
.groupByKey(_.SECURITY_ID)
.mapGroups{
case (nameKey, df) => {
allocOneProcess(df,)
}
}