使用多列数据计算文本文件的中位数和平均值

时间:2015-07-20 17:55:13

标签: linux bash unix math awk

我有一个包含多列数据的文件。

我需要计算两列的中位数和平均值。

输入:

67 65
56 43
87 87
90 65
95 34
87 76
85 65
87 89
73 34
72 56
98 33
95 84
84 79

期望的输出:

67 65 AVERAGE MEDIAN
56 43 AVERAGE MEDIAN
87 87 AVERAGE MEDIAN
90 65 AVERAGE MEDIAN
95 34 AVERAGE MEDIAN
87 76 AVERAGE MEDIAN
85 65 AVERAGE MEDIAN
87 89 AVERAGE MEDIAN
73 34 AVERAGE MEDIAN
72 56 AVERAGE MEDIAN
98 33 AVERAGE MEDIAN
95 84 AVERAGE MEDIAN
84 79 AVERAGE MEDIAN

我试过了

cat master | awk 'BEGIN {c = 0; sum = 0;} $1 ~ /^[0-9]*(\.[0-9]*)?$/ {a[c++] = $1; sum += $1;} END {avg = sum / c; if( (c % 2) == 1 ) {median = a[ int(c/2) ];} else {median = ( a[c/2] + a[c/2-1] ) / 2;} OFS="\t"; print avg, median;}' master

仅适用于一列数据。

2 个答案:

答案 0 :(得分:4)

有两个数字,平均值等于中位数。

awk '{print $0 " " ($1+$2)/2 " " ($1+$2)/2}' file

输出:

67 65 66 66
56 43 49.5 49.5
87 87 87 87
90 65 77.5 77.5
95 34 64.5 64.5
87 76 81.5 81.5
85 65 75 75
87 89 88 88
73 34 53.5 53.5
72 56 64 64
98 33 65.5 65.5
95 84 89.5 89.5
84 79 81.5 81.5

答案 1 :(得分:3)

这里我假设您打算使用列并计算两组值。但是你的输出格式并没有反映出这个假设。

最好为此任务编写函数。但是,您的实现开始时是不正确的。对于中位数,您必须先对值进行排序。中点计算也不正确。

{
  c1[NR]=$1
  c2[NR]=$2
}
END {
  print mean(c1) FS mean(c2)
  print median(c1) FS median(c2)
}

function mean(arr) {
  for(i in arr) {sum += arr[i]; k++}
  return sum / k
}

function median(arr) {
  n=asort(arr)
  if(n%2) {
    mid = (n+1)/2
    return arr[mid]
  } else {
    mid = n/2
    return (arr[mid]+arr[mid+1])/2
  }
}