我在spark中有Dataframe。看起来像这样:
+-------+----------+-------+
| value| group| ts|
+-------+----------+-------+
| A| X| 1|
| B| X| 2|
| B| X| 3|
| D| X| 4|
| E| X| 5|
| A| Y| 1|
| C| Y| 2|
+-------+----------+-------+
我想知道有多少个序列 A-B-E
(序列只是后续行的列表)有。添加了一个约束,序列的后续部分可以是最大的 n
排成一排。让我们考虑一下这个例子 n
是2。
考虑组 X
. 在这种情况下,正好有1 D
介于 B
以及 E
(连续多次) B
已忽略)。这意味着 B
以及 E
是一行分开,因此有一个序列 A-B-E
我考虑过使用 collect_list()
,创建一个字符串(如dna)并使用regex进行子字符串搜索。但我想知道是否有一种更优雅的分布式方式,也许是使用窗口函数?
编辑:
请注意,提供的Dataframe只是一个示例。真正的Dataframe(以及组)可以是任意长的。
1条答案
按热度按时间hjzp0vay1#
编辑以回答@tim的评论+修复类型为“aabe”的模式
是的,使用窗口函数有帮助,但是我创建了一个
id
订购:然后lag将收集所需的内容,但是需要一个函数来生成
Column
表达式(请注意拆分以消除“aabe”的重复计数。警告:这将拒绝“abaexx”类型的模式:因为
Column
api,使用udf完全避免regex要容易得多概括(超出范围)
如果你想把它概括为一系列较长的字母,这个问题就必须概括。它可能是微不足道的,但在这种情况下,类型(“abae”)的模式应该被拒绝(参见注解)。因此,最简单的概括方法是在下面的实现中使用成对规则(我添加了一个组“z”来说明这个算法的行为)
首先我们定义一对的逻辑
然后,我们定义一个函数,将这个逻辑迭代地应用于Dataframe
由于我们首先对从第一个字符开始的序列进行滤波,所以得到了简化和优化
(
transform
是一层简单的糖衣DataFrame => DataFrame
(转换)正如我所说的,在扫描序列时,有不同的方法来概括“重置规则”,但是这个例子希望能帮助实现更复杂的规则。