如何在pyspark中使用groupby的聚合表达式列表?

就在这儿

我有一个包含 2 列的数据框,如下所示:

+----+---+
|ptyp|sID|
+----+---+
|  CO|111|
|  CO|222|
|  CO|222|
|  CO|222|
|  CO|111|
|  CD|111|
|  CD|222|
|  CD|222|
|  CD|333|
|  CD|333|
|  CD|333|
|  AG|111|
|  AG|111|
|  AG|111|
|  AG|222|
+----+---+

给定一个输入n,对于每个pytp,我想添加显示顶部的列n sIDs(就它们出现的次数而言pytp)。我还想打印每个组sID在列中出现的次数sIDval

例如,如果n = 2,我希望输出是这样的:

+----+-------+-----------+-------+-----------+
|ptyp|topSID1|topSID1_val|topSID2|topSID2_val|
+----+-------+-----------+-------+-----------+
|  AG|    111|          3|    222|          1|
|  CO|    222|          3|    111|          2|
|  CD|    333|          3|    222|          2|
+----+-------+-----------+-------+-----------+

UDFs用来计算这个:

@F.udf
def mode(x, top_rank):
    c = Counter(x).most_common(top_rank)
    sz = len(c)
    return c[min(top_rank-1, sz-1)][0]

@F.udf
def modeval(x, top_rank):
    c = Counter(x).most_common(top_rank)
    sz = len(c)
    return c[min(top_rank-1, sz-1)][1]

我将每个新列所需的聚合表达式存储在列表中newcols

newcols = []
n = 3

for r in range(1, num_ranks+1):
    newcols.append([mode(F.collect_list('sID'), F.lit(r)).alias('topSID' + str(r))])
    newcols.append([modeval(F.collect_list('sID'), F.lit(r)).alias('topSID' + str(r) +'_val')])

现在,如果我知道n=3,我可以这样做:

df.groupBy('ptyp').agg(*newcols[0], *newcols[1], *newcols[2], \
                       *newcols[3], *newcols[4], *newcols[5])

有没有一种方法可以将其概括为 的任何值n我试过了

df.groupBy('ptyp').agg([*e for e in new_cols])

df.groupBy('ptyp').agg((*e for e in new_cols))

以及更多变体,但所有变体都会出错。

现在我已经求助于一次聚合一个并进行连接,但这非常昂贵。

有没有办法以我上面尝试过的方式做到这一点?

克罗诺克

列表理解是正确的方法,但您无法提取子列表,*因为它们没有目标。你打电话的时候:

print(*newcols[0])

您会得到如下输出:

Column<b'mode(collect_list(sID, 0, 0), 1) AS `topSID1`'>

newcols 是一个列表列表,您可以使用另一种列表理解来扁平化这个列表列表。

print([item for sublist in newcols for item in sublist][0])

返回相同的输出:

Column<b'mode(collect_list(sID, 0, 0), 1) AS `topSID1`'>

因此,您可以执行以下操作以获得预期的行为:

df.groupBy('ptyp').agg(*[item for sublist in newcols for item in sublist])

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章