【发布时间】:2018-09-05 15:24:32
【问题描述】:
DF1 是我现在拥有的,我想让 DF1 看起来像 DF2。
期望的输出:
DF1 DF2
+---------+----------------------------------------+ +---------+-------------------------------------------------------------------+
| ID | Category | | ID | category_name |
+---------+----------------------------------------+ +---------+-------------------------------------------------------------------+
| 31898 | CP Bill Payment | | 31898 | CP Bill Payment + CP e-Transfer + CP IMT (CPS Limit + CPS Payee) |
| 31898 | CP e-Transfer + CP IMT | | 32614 | CP Bill Payment + CP e-Transfer + CP Other Transfer (CPS Blocked)|
| 31898 | CPS Limit + CPS Payee | | 35431 | CP Bill Payment + CP e-Transfer |
| 32614 | CP e-Transfer + CP Other Transfer | | 33987 | CP IMT (CPS Limit) |
| 32614 | CP Bill Payment | =====> | 35672 | CPS Blocked |
| 32614 | CPS Blocked | =====> | 37612 | CPS Blocked + CPS Stop/Cancel/Reverse |
| 35431 | CP e-Transfer | +---------+-------------------------------------------------------------------+
| 35431 | CP Bill Payment |
| 33987 | CP IMT |
| 33987 | CPS Limit |
| 35672 | CPS Blocked |
| 37612 | CPS Blocked + CPS Stop/Cancel/Reverse|
+---------+----------------------------------------+
我有以下代码:
val DF2 = DF1.groupBy("ID").agg(collect_set("Category").as("CategorySet"))
.groupBy("ID")
.agg(collect_set("Category").as("CategorySet"))
.withColumn( "category_name",
when(array_contains($"CategorySet", "CP Bill Payment") && array_contains($"CategorySet", "CP e-Transfer + CP IMT") && array_contains($"CategorySet", "CPS Limit + CPS Payee"), "CP Bill Payment + CP e-Transfer + CP IMT (CPS Limit + CPS Payee)").otherwise("---other conditions---"))
.select("ID","category_name")
逻辑是对于同一个ID,31898/32614/33987:如果包含CP*和CPS*,应该是CP*(CPS*)或者CP*+CP*(CPS*); 35431:如果数组中没有 CPS*,只需使用 + 连接数组中的所有元素; 35672/37612:否则,只是数组中的元素。顺便说一句,Category 应该按升序排序。
代码有效,只是可能的组合太多了。如何使用 UDF 做同样的事情?或者是否有任何内置函数可以做到这一点?提前谢谢你
【问题讨论】:
-
您可以创建多个 UDAF 来包含您需要的逻辑。
-
你能给我举个例子吗?对scala udf不太熟悉
-
你的ID是String类型吗?
-
十进制 (28,0)
标签: scala apache-spark dataframe user-defined-functions