如何使用AWK计算数字数据列的中位数?
我可以想到一个简单的算法,但似乎无法编写它:
目前我所拥有的是:
sort | awk 'END{print NR}'
使用这个命令可以得到列中元素的数量。我想用它来打印某一行(NR / 2)
。如果NR/2
不是整数,则将其四舍五入到最近的整数,并作为中位数,否则取(NR/2)+1
和(NR/2)-1
的平均值。
使用 awk
,您需要将值存储在数组中,在最后计算中位数,假设我们查看第一列:
sort -n file | awk ' { a[i++]=$1; } END { print a[int(i/2)]; }'
确实,对于真实中位数的计算,请按照问题描述进行四舍五入:
sort -n file | awk ' { a[i++]=$1; }
END { x=int((i+1)/2); if (x < (i+1)/2) print (a[x-1]+a[x])/2; else print a[x-1]; }'
这个 awk
程序假设有一个数字排序后的数据列:
#/usr/bin/env awk
{
count[NR] = $1;
}
END {
if (NR % 2) {
print count[(NR + 1) / 2];
} else {
print (count[(NR / 2)] + count[(NR / 2) + 1]) / 2.0;
}
}
使用示例:
sort -n data_file | awk -f median.awk
好的,我看到这个主题,想分享一下我的意见,因为我以前也在寻找类似的东西。尽管标题中包含awk
,但所有答案都使用了sort
。使用datamash可以轻松计算数据列的中位数:
> seq 10 | datamash median 1
5.5
sort
函数:> seq 10 | gshuf | datamash median 1
5.5
这份文档列出了 datamash
能执行的所有功能,还为包含多列的文件提供了好的示例。无论如何,它与 awk
没有任何关系,但我认为在这种情况下,datamash
会非常有帮助,并且也可以与 awk
结合使用。希望对某些人有所帮助!
array=(5 6 4 2 7 9 3 1 8) # numbers 1-9
IFS=$'\n'
median=$(awk '{arr[NR]=$1} END {if (NR%2==1) print arr[(NR+1)/2]; else print (arr[NR/2]+arr[NR/2+1])/2}' <<< sort <<< "${array[*]}")
unset IFS
asort
来对数组进行排序。 - Vatinecount[NR] = $1;
时,NR == 1
。我相信这段代码是正确的(但是,五年后,我不喜欢count
作为变量名)。 - johnsyweb