平均每N行,并将平均值追加为新列,最好在ceil(N / 2)位置

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

我对awk还是很陌生,我曾尝试从AWK binning every N lines修改解决方案,但很遗憾,我没有设法将平均值作为新列正确添加到我的文件中。

在第一列中,我有日期/时间戳,然后在下一列中,有一些数据。我需要一个数据列(后来可能更多)中每N行的平均值。作为第一个解决方案,我尝试将特定的平均值写在第N行旁边作为新列,并且中间没有相应的行条目(例如,对于N = 100:从0-99开始,没有新的输出,但在第100行中,我从所选列中获取了最近100个值的平均值)

我的最终目标是将计算出的平均值附加到每一ceil(N / 2)行。这样N = 100的平均值将附加到第50行。

由于我仅有有限的知识和资源来解决此问题,我可能会多次运行awk并尝试先将结果输出到临时文件,然后再尝试将其合并。

非常感谢!

PS:实际上,它不必只是awk,我只是认为这可能是最合适的解决方案。

编辑:我的数据如下:

-9,787440e+00;1,8;29,2;0,0033;0,0405;-0,0006;0,0102
-9,787360e+00;-1,90735e-07;28,8;0,0017;0,0033;0,00012;-0,00956
-9,787280e+00;-1,90735e-07;29,4;0,0017;0,0405;0,00036;0,0102
-9,787200e+00;1,8;29;0,0033;0,0093;0,00156;-0,00764
-9,787120e+00;8;29,4;0,0093;0,0405;0,00316;0,0102
-9,787040e+00;15,6;29;0,0167;0,0129;0,00332;-0,00636

在第一列中,我有相对时间戳,其他值是测量值。现在假设对于N = 3,我需要新列中第6列的平均值。理想情况下,结果应如下所示:

-9,787440e+00;1,8;29,2;0,0033;0,0405;-0,0006;0,0102
-9,787360e+00;-1,90735e-07;28,8;0,0017;0,0033;0,00012;-0,00956**;−0,00004**
-9,787280e+00;-1,90735e-07;29,4;0,0017;0,0405;0,00036;0,0102
-9,787200e+00;1,8;29;0,0033;0,0093;0,00156;-0,00764
-9,787120e+00;8;29,4;0,0093;0,0405;0,00316;0,0102**;0,00268**
-9,787040e+00;15,6;29;0,0167;0,0129;0,00332;-0,00636

我试图将新添加的条目标记为粗体**。因此,对于N = 3,应在每个平均窗口的中间添加第6列的每3行的平均值。在这种情况下,ceil(3/2)= 2在计算新的平均值之后每隔第二行显示一次。

编辑2:我设法将计算出的平均值附加到第N行-现在,我需要将其移回N / 2行。使用awk或其他bash工具可以通过某种方式实现吗?总体而言,它应该相当快-我必须经过65Mb的.csv文件。非常感谢!

BEGIN { 
N=3
OFS=FS = ";";
}

{ 
    sum+=$1
}

{
    if (NR%N==0) {
        my_add_col=sum/N
        sum=0
        $(NF+1)=my_add_col
    }
}

{
    print $0
}
bash awk moving-average
1个回答
0
投票

让我假设;

  • 小数点分隔符是逗号。
  • 记录数是N的倍数。

然后您可以尝试以下操作:

LC_ALL=fr_FR.UTF-8 awk --use-lc-numeric -F";" -v N=3 '
    {
        sum += $6               # accumulate the value in the 6th field
        list[(NR-1)%N+1] = $0   # store current line in an array (to be displayed later)
    }
    NR%N==0 {                   # the line number is a multiple of N
        ave = sum / N
        ceil = int((N + 1) / 2) # the line to add the column of the average
        for (i = 1; i < ceil; i++) print list[i]
        print list[ceil] ";" ave
        for (i = ceil + 1; i <= N; i++) print list[i]

        sum = 0                 # initialize sum for the next iteration
        delete list             # initialize list of lines
    }
' data.txt
© www.soinside.com 2019 - 2024. All rights reserved.