使用collect_list时如何保留列的顺序?我有一个日期列(col1),当我在其上调用collect_list函数时,顺序不会保留。这是我的示例输入和输出代码。
输入数据框:
df = sqlContext.createDataFrame([('1', 201001,3400,1600,65,320,400,), ('1', 201002,5200,1600,65,320,400,), ('1', 201003,65,1550,32,320,400,), ('2', 201505,3200,1800,12,1,40,), ('2', 201508,3200,3200,12,1,40,), ('3', 201412,40,40,12,1,3,)],
['ColA', 'Col1','Col2','Col3','Col4','Col5','Col6',])
+----+------+----+----+----+----+----+
|ColA| Col1|Col2|Col3|Col4|Col5|Col6|
+----+------+----+----+----+----+----+
| 1|201001|3400|1600| 65| 320| 400|
| 1|201002|5200|1600| 65| 320| 400|
| 1|201003| 65|1550| 32| 320| 400|
| 2|201505|3200|1800| 12| 1| 40|
| 2|201508|3200|3200| 12| 1| 40|
| 3|201412| 40| 40| 12| 1| 3|
+----+------+----+----+----+----+----+
预期的输出量:
df = sqlContext.createDataFrame([(1,['201001', '201002', '201003'],[3400, 5200, 65],[1600, 1600, 1550],[65,32],[320],[400],), (2,['201505', '201508'],[3200, 3200],[1800, 3200],[12],[1],[40],),
(3,['201412'],[40],[40],[12],[1],[3],)], ['ColA', 'Col1','Col2','Col3','Col4','Col5','Col6',])
df.show()
+----+--------------------+----------------+------------------+--------+-----+-----+
|ColA| Col1| Col2| Col3| Col4| Col5| Col6|
+----+--------------------+----------------+------------------+--------+-----+-----+
| 1|[201001, 201002, ...|[3400, 5200, 65]|[1600, 1600, 1550]|[65, 32]|[320]|[400]|
| 2| [201505, 201508]| [3200, 3200]| [1800, 3200]| [12]| [1]| [40]|
| 3| [201412]| [40]| [40]| [12]| [1]| [3]|
+----+--------------------+----------------+------------------+--------+-----+-----+
这是有效的代码,但不存储col1的顺序:
def aggregation(df, groupby_column, cols_to_list, cols_to_set):
exprs = [F.collect_list(F.col(c)).alias(c) for c in cols_to_list]\
+ [F.collect_set(F.col(c)).alias(c) for c in cols_to_set]
return df.groupby(*groupby_column).agg(*exprs)
groupby_column = ['ColA']
cols_to_list = ['Col1', 'Col2', 'Col3',]
cols_to_set = ['Col4', 'Col5', 'Col6',]
df = aggregation(df, groupby_column, cols_to_list, cols_to_set)
答案 0 :(得分:0)
由于@pault,我能够理解问题所在。在另一页上发布的解决方案很复杂,特别是如果您有太多要处理的列并计划同时使用collect_list和collect_set函数的话。我能够通过与重新分区配对执行orderBy来解决该问题,因此我的所有数据都位于单个分区上,而不是多个分区上,这导致了问题的开始。请记住,重新分区是一项昂贵的操作,因此请谨慎使用。
以下是任何人列表的代码:
def aggregation(df, groupby_column, cols_to_list, cols_to_set):
df = df.orderBy(colA).repartition(1)
exprs = [F.collect_list(F.col(c)).alias(c) for c in cols_to_list]\
+ [F.collect_set(F.col(c)).alias(c) for c in cols_to_set]
return df.groupby(*groupby_column).agg(*exprs)
groupby_column = ['ColA']
cols_to_list = ['Col1', 'Col2', 'Col3',]
cols_to_set = ['Col4', 'Col5', 'Col6',]
df = aggregation(df, groupby_column, cols_to_list, cols_to_set)