【发布时间】:2018-04-02 13:54:43
【问题描述】:
我最初有一个如下的 DataFrame:
Key Emails PassportNum Age
0001 [Alan@gmail,Alan@hotmail] passport1 23
0002 [Ben@gmail,Ben@hotmail] passport2 28
我需要对每封电子邮件应用一个函数,例如在末尾添加“_2”之类的虚拟函数,该操作不相关。所以我会这样爆这个专栏:
val dfExplode = df.withColumn("Email",explode($"Emails")).drop("Emails")
现在我将有一个这样的数据框:
Key Email PassportNum Age
0001 Alan@gmail passport1 23
0001 Alan@hotmail passport1 23
0002 Ben@gmail passport2 28
0002 Ben@hotmail passport2 28
我在护照上应用了任何更改,然后我想要的又是这样的:
Key Emails PassportNum Age
0001 [Alan_2@gmail,Alan_2@hotmail] passport1 23
0002 [Ben_2@gmail,Ben_2@hotmail] passport2 28
我正在考虑的选项是这样的:
dfOriginal = dfExploded.groupBy("Key","PassportNum","Age").agg(collect_set("Email").alias("Emails"))
在这种情况下,这可能不是一个糟糕的方法。但在我的真实案例中,我在单个列上执行分解,我还有另外 20 个列,例如 PassportNum、Age... 将被复制。
这意味着我需要在 groupBy 中添加大约 20 列,当我真的可以通过单个列执行 group by 时,例如唯一的 Key。
我正在考虑在 agg 中添加这些列,如下所示:
dfOriginal = dfExploded.groupBy("Key").agg(collect_set("Email").alias("Emails"),collect_set("PassportNum"),collect_set("Age"))
但我不希望它们位于单个元素数组中。
有没有办法在没有任何collect_* 的情况下进行聚合?有没有更简单的方法来撤消explode?
【问题讨论】:
-
你不应该使用
first来表示PassportNum和Age,因为它们在爆炸后无论如何都会有相同的值吗? -
你的意思是先收集后使用?
标签: scala apache-spark dataframe