java - 避免在特定情况下使用 apache spark sql 的数据帧中具有相同域的多个列进行多次连接
问题描述
我被要求通过数据帧在 apache spark sql (java api) 中做一些事情,我认为如果按照幼稚的方法执行会花费很多(我仍在使用幼稚的方法,但我认为这会花费很多因为它至少需要 4 种连接)。
我得到以下数据框:
+----+----+----+----+----+----------+------+
| C1| C2| C3| C4| C5|UNIQUE KEY|points|
+----+----+----+----+----+----------+------+
| A| A|null|null|null| 1234| 2|
| A|null|null| H|null| 1235| 3|
| A| B|null|null|null| 1236| 3|
| B|null|null|null| E| 1237| 1|
| C|null|null| G|null| 1238| 1|
| F|null| C| E|null| 1239| 2|
|null|null| D| E| G| 1240| 1|
+----+----+----+----+----+----------+------+
C1、C2、C3、C4 和 C5 具有相同的域值,唯一键是唯一键,点是一个整数,对于其对应 C 列的每个不同值(例如,对于第一行 A、A ,null,null,null,key,2 与 A,null,null,null,null,key,2 或 A,A,A,A,null,key,2 相同)
我被要求“为每个现有的 C 值获取总点数”。
所以输出应该是:
+----+------+
| C1|points|
+----+------+
| A| 8|
| B| 4|
| C| 3|
| D| 1|
| E| 4|
| F| 2|
| G| 2|
| H| 3|
+----+------+
我打算通过 simple 将数据框分成多个小数据框(C 列为 1 列,点为 1 列).select("C1","point")
,.select("C2","point")
依此类推。但是我相信如果数据量真的很大,那真的会花很多钱,我相信应该有一些通过map reduce的技巧,但我自己找不到,因为我对这一切还很陌生世界。我想我错过了一些关于如何应用地图缩减的概念。
我还考虑过使用该函数explode
,我想将 [C1, C2, C3, C4, C5] 放在一列中然后使用explode所以我每行得到5行然后我只是按键分组......但我相信这会在某些时候增加数据量,如果我们谈论的是 GB,这可能不可行......我希望你能找到我正在寻找的技巧。
谢谢你的时间。
解决方案
使用explode
可能是去这里的方式。与使用多个相比,它不会增加数据量并且在计算上更有效join
(请注意,单个join
本身是一项昂贵的操作)。
在这种情况下,您可以将列转换为数组,只保留每个单独行的唯一值。然后可以分解该数组并过滤掉所有空值。在这一点上,一个简单的groupBy
和求和会给你想要的结果。
在斯卡拉:
df.select(explode(array_distinct(array("C1", "C2", "C3", "C4", "C5"))).as("C1"), $"points")
.filter($"C1".isNotNull)
.groupBy($"C1)
.agg(sum($"points").as("points"))
.sort($"C1") // not really necessary
这会给你想要的结果:
+----+------+
| C1|points|
+----+------+
| A| 8|
| B| 4|
| C| 3|
| D| 1|
| E| 4|
| F| 2|
| G| 2|
| H| 3|
+----+------+
推荐阅读
- amazon-web-services - 如何将 ECS 集群状态设置为 ACTIVE
- javascript - 如何更新Javascript中对象列表中某个键的值?
- javascript - 确保 `this` 指向 API 实例方法中的类的实例
- python - 选择随机验证数据集
- sonarqube - 嗨,谁能解释一下为什么我们需要在声纳 qube 中生成一个令牌?是否强制?如果它是强制性的,你能解释一下为什么吗?
- java - 如何使用远程进程通过 jconsole 连接到本地应用程序?
- angular - 使用 tick 和 fakeAsync 对 Observable 进行单元测试角度组件
- javascript - CKEditor5,如何测试简单插件的概念证明?
- intellij-idea - IntelliJ - 语言级别 5 不支持菱形类型和 Lambda 表达式
- javascript - 如何使用 jquery 访问 $(this) 关键字下的子元素