`awk` 可以对指定行数的列求和吗

`awk` 可以对指定行数的列求和吗

我查看了“类似问题”,但似乎没有一个能解决我的问题:

我有一个很大的 CSV 输入文件;文件中的每一行都是一个x,y数据点。这里有几行用于说明,但请注意,一般来说数据不是 单调的:

1.904E-10,2.1501E+00  
3.904E-10,2.1827E+00  
5.904E-10,2.1106E+00  
7.904E-10,2.2311E+00  
9.904E-10,2.2569E+00  
1.1904E-09,2.3006E+00  

我需要创建一个小于输入文件的输出文件。输出文件将包含不多于 一条线对于每一个N 行在输入文件中。输出文件中的每一行都是一个x,y数据点,即平均的x,yN 行输入文件的。

例如,如果输入文件中的总行数为 3,000,并且N=3,输出文件将包含不多于1,000 行。使用上面的数据来完成此示例,上面的前 3 行数据将替换为单行,如下所示:

x = (1.904E-10 + 3.904E-10 + 5.904E-10) / 3 = 3.904E-10

y = (2.1501E+00 + 2.1827E+00 + 2.1106E+00) / 3 = 2.1478E+00,或:

3.904E-10,2.1478E+00 

对于输出文件的一行。

我已经摆弄这个有一段时间了,但还没有弄好。这就是我一直在处理的问题,但我不知道如何做迭代NR遍历整个文件的值:

awk -F ',' 'NR == 1, NR == 3 {sumx += $1; avgx = sumx / 3; sumy += $2; avgy = sumy / 3} END {print avgx, avgy}' CB07-Small.csv

为了使这个问题变得更加复杂,我需要进一步“精简”我的输出文件:

avgy如果(如上计算)的值为关闭对于输出文件中的最后一个值avgy,我不会将其作为新数据点添加到输出文件中。相反,我将计算下一个avgx&avgy下一个的值N 行输入文件的。“关闭”应定义为 的最后一个值的百分比argy。例如:

如果 的当前计算值avgy与输出文件中记录的最后一个值相差不到 10% avgy,则不要将新值写入输出文件。

查看编辑历史记录

答案1

这是一个通用变体:

BEGIN { OFS = FS = "," }

{
    for (i = 1; i <= NF; i++) sum[i] += $i
    count++
}

count % 3 == 0 {
    for (i = 1; i <= NF; i++) $i = sum[i] / count
    delete sum
    count = 0
    if ($NF >= 1.1 * last || $NF <= 0.9 * last) {
        print
        last = $NF
    }
}


END {
    if (count > 0) {
        for (i = 1; i <= NF; i++) $i = sum[i] / count
        if ($NF >= 1.1 * last || $NF <= 0.9 * last) print
    }
}

我假设剩菜应该以与大块类似的方式处理线。

答案2

这会检查线路状况和 10% 规则。请记住,10% 规则具有线性增加检查值的副作用。

$ awk -F ',' '
  BEGIN{
    N=3; prev_y=0
  }
  {
    x+=$1;
    y+=$2;
    i++
  }
  NR%N==0 && (y/i) <= (prev_y)*1.1{ x=0; y=0; i=0 }
  NR%N==0 && (y/i) > (prev_y)*1.1{
    print x/i","y/i;
    prev_y=y/i; x=0; y=0; i=0
  }' file

相关内容