PySpark:如何在宽度可变的列数组上聚合?

时间:2019-11-22 18:47:53

标签: python-3.x apache-spark pyspark

我正在尝试汇总并创建一系列手段(这是最小的工作示例):

n = len(allele_freq_total.select("alleleFrequencies").first()[0])

allele_freq_by_site = allele_freq_total.groupBy("contigName", "start", "end", "referenceAllele").agg(
  array(*[mean(col("alleleFrequencies")[i]) for i in range(n)]).alias("mean_alleleFrequencies")

使用我从

获得的解决方案

Aggregate over column arrays in DataFrame in PySpark?

但是问题是n是可变的,我该如何更改

array(*[mean(col("alleleFrequencies")[i]) for i in range(n)])

以便将可变长度考虑在内?

1 个答案:

答案 0 :(得分:0)

如果不同组中的数组大小不相等(对您来说,一个组是("contigName", "start", "end", "referenceAllele"),我将其简单地重命名为group),则可以考虑展开数组列({{ 1}}),并引入位置值,这些值在数组中具有。这将为您提供一个额外的列,您可以在分组中使用该列来计算您想到的平均值。此时,您实际上可能已经足够进行进一步的计算(请参见下面的alleleFrequencies)。

如果您真的必须将其放回数组中,那会比较困难,我也不知道。必须跟踪订单的顺序,我相信使用地图(如果需要,可以使用字典)很容易。为此,我在两列上使用了聚合函数df3.show()。尽管collect_list不是确定性的(您不知道列表中返回值的顺序,因为行被乱码了),但两个数组的聚合将保留其顺序,因为行被乱码完整(请参见下面的collect_list)。在此处,您可以使用df4.show()创建位置到平均值的映射。

示例:

map_from_arrays