如果我有
ID Name Code Value
1 Person1 A 12
1 Person2 B 15
而我做了一个
df.groupBy("ID").agg(
collect_set("Name").alias("Name"),
collect_set("Code").alias("Code"),
collect_set("Value").alias("Value")
)
我可能会得到一个
1, [Person1, Person2], [B,A], [15,12]
我需要得到一个
1, [Person1, Person2], [A,B], [12,15]
我如何确保所有列的顺序相同?
我的实际DF有70列,我需要按一列进行分组,并按照正确的顺序为每列挑选前5个唯一的值。
如有任何建议,深表感谢
你不能确定你的集合的顺序,我建议把属性打包在一个结构中,这样你会得到一个数组而不是3个。
df.groupBy("ID").agg(
collect_list(struct("Name","Code","Value").as("Attribute")).as("Attributes")
)
集合不保留顺序。但是你可以在对数组进行 collect_list
借用 satellite data
.
你可以在前面加上 Person
名称的属性,如下图所示。
val df2 = df.map(each => {
val person = each.getString(1)
(each.getInt(0), person + "|" + each.getString(1), person + "|" + each.getString(2), person + "|" + each.getInt(3))
}).toDF("ID","Name","Code","Value")
现在,你可以使用 sort_array
之后 collect_list
,它将会对所有属性进行排序,按照 Name
的人
val df3 = df2.groupBy("ID").agg(
sort_array(collect_set("Name")).alias("Name"),
sort_array(collect_set("Code")).alias("Code"),
sort_array(collect_set("Value")).alias("Value"))
请注意,每个属性都在结果列表中附加了人的信息。
df3.show
+---+--------------------+--------------------+--------------------+
| ID| Name| Code| Value|
+---+--------------------+--------------------+--------------------+
| 1|[Person1|Person1,...|[Person1|A, Perso...|[Person1|12, Pers...|
+---+--------------------+--------------------+--------------------+