我查看了“类似问题”,但似乎没有一个能解决我的问题:
我有一个很大的 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,y
值N 行输入文件的。
例如,如果输入文件中的总行数为 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