平均每 N 行并将平均值附加为新列,理想情况下在 ceil(N/2) 位置

Average every N lines and append the average as a new column, ideally at ceil(N/2) position

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

在第一列中我有 date/time 个邮票,然后在接下来的列中有一些数据。我需要一个(以后可能更多)数据列的每 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 行的平均值应添加到每个平均值的中间 window。在这种情况下,ceil(3/2)=2 在计算新平均值后每隔一行。

编辑 2: 我设法在每第 N 行附加计算的平均值 - 现在我需要将其移回 N/2 行。这是否可以通过 awk 或其他一些 bash 工具以某种方式实现?总的来说,它应该相当快——我必须浏览 65Mb 的 .csv 文件。非常感谢!

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

{ 
    sum+=
}

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

{
    print [=13=]
}

让我假设;

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

那么请您尝试以下操作:

LC_ALL=fr_FR.UTF-8 awk --use-lc-numeric -F";" -v N=3 '
    {
        sum +=                # accumulate the value in the 6th field
        list[(NR-1)%N+1] = [=10=]   # 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