使用 GNU 并行计算多个文件的总体中位数

问题描述 投票:0回答:1

我有以下命令:

find 01/ -type f -name '*.csv.gz' | parallel "pigz -dc {} | datamash -t, median 3"

此命令对于“01/”目录中找到的每个 .csv.gz 文件,解压缩该文件并计算每个文件第三列中值的中位数。但是,我希望计算所有文件的总体中位数,而不是单独计算每个文件的中位数。

附注我尝试过跑步:

find 01/ -type f -name '*.csv.gz' | parallel "pigz -dc {} | datamash -t, median 3" | datamash median 1

但这似乎提供了“中位数的中位数”,这不是我正在寻求的结果。

bash median gnu-parallel
1个回答
1
投票

这确实是一条评论,但太长了。

要获得 n 个数字的精确中位数,您需要 O(n) 空间。这是因为,如果魔鬼设计输入,他可以强制序列中的任何位置作为中位数,并且在您读取至少 n/2 个数字之前,您将无法排除任何位置。

但是,如果魔鬼没有设计输入,并且输入或多或少是随机或正态分布的,那么我们可以使用 Remedian 在大多数情况下获得正确的值(Rousseeuw、Peter J. 和 Gilbert W) Bassett Jr.“补救措施:大型数据集的稳健平均方法。”美国统计协会杂志 85.409(1990):97-104)。 Remedian 使用 O(1) 空间。

GNU Parallel 在

set_remedian

 内部使用 Remedian;是的:它确实只有 ~10 行代码。

https://git.savannah.gnu.org/cgit/parallel.git/tree/src/parallel#n14377

所以我会运行类似的东西:

find 01/ -type f -name '*.csv.gz' -exec pigz -dc {} + | awk '{print $3}' | remedian
其中 

remedian

 是您的 Remedian 实现。

© www.soinside.com 2019 - 2024. All rights reserved.