linux - 计算不规则间隔的平均值而不考虑shell脚本中的缺失值?

标签 linux shell awk

我有一个数据集,其中有许多缺失值,如 -999。部分数据为

input.txt
30
-999
10
40
23
44
-999
-999
31
-999
54
-999 
-999
-999
-999
-999
-999
10
23
2
5
3
8
8
7
9
6
10
and so on

我想计算每个 5,6,6 行间隔的平均值,而不考虑缺失值。

期望输出为

ofile.txt
25.75   (i.e. consider first 5 rows and take average without considering missing values, so (30+10+40+23)/4)
43      (i.e. consider next 6 rows and take average without considering missing values, so (44+31+54)/3)
-999    (i.e. consider next 6 and take average without considering missing values. Since all are missing, so write as a missing value -999)
8.6     (i.e. consider next 5 rows and take average (10+23+2+5+3)/5)
8     (i.e. consider next 6 rows and take average)

如果是定期间隔(比方说 5),我可以这样做

awk '!/\-999/{sum += $1; count++} NR%5==0{print count ? (sum/count) :-999;sum=count=0}' input.txt

我在这里定期问了类似的问题Calculating average without considering missing values in shell script?但这里我问的是不规则间隔的解决方案。

最佳答案

使用AWK

awk -v f="5" 'f&&f--&&$0!=-999{c++;v+=$0} NR%17==0{f=5;r++} 
!f&&NR%17!=0{f=6;r++} r&&!c{print -999;r=0} r&&c{print v/c;r=v=c=0}
END{if(c!=0)print v/c}' input.txt

输出

25.75
43
-999
8.6
8

分割

f&&f--&&$0!=-999{c++;v+=$0} #add valid values and increment count
NR%17==0{f=5;r++} #reset to 5,6,6 pattern 
!f&&NR%17!=0{f=6;r++} #set 6 if pattern doesnt match
r&&!c{print -999;r=0} #print -999 if no valid values
r&&c{print v/c;r=v=c=0} #print avg
END{
 if(c!=0) #print remaining values avg
  print v/c
}

关于linux - 计算不规则间隔的平均值而不考虑shell脚本中的缺失值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38516981/

相关文章:

linux - 这个 cronjob 行是什么意思

windows - 什么是 wget 以及如何从公共(public)目录获取图像?

python - 如何为每个字符分配值并使用 python 或 awk 找到平均值?

Linux命令向xml文件中插入多行

linux - 连接后如何确定 SSH 使用的传出端口?

linux - 在 bash 中获取 "310"这样的 linux 内核版本?

linux - grep 在表达式中不使用 0

c - 如何转发/多路复用 ioctl 组?

shell - "Exception handling"在 shell 脚本中

linux - 如何将一行分成多行?