有很多方法可以忽略除数为零的行,包括:
awk '$3 != 0 { print $1/$3 }' your-data-file
awk '{ if ($3 != 0) print $1/$3 }' your-data-file
问题变了——改为打印 0。答案并不难:
awk '{ if ($3 != 0) print $1/$3; else print 0 }' your-data-file
中位数和其他百分位数更难处理。如果数据按排序顺序排列是最简单的。如此简单,我希望使用数字排序,然后从那里处理数据。
我挖出了一个旧的 shell 脚本,它计算描述性统计数据 - 单个数字列的最小值、最大值、众数、中位数和十分位数:
: "@(#)$Id: dstats.sh,v 1.2 1997/06/02 21:45:00 johnl Exp $"
#
# Calculate Descriptive Statistics: min, max, median, mode, deciles
sort -n $* |
awk 'BEGIN { max = -999999999; min = 999999999; }
{ # Accumulate basic data
count[$1]++;
item[++n] = $1;
if ($1 > max) max = $1;
if ($1 < min) min = $1;
}
END { # Print Descriptive Statistics
printf("# Count = %d\n", n);
printf("# Min = %d\n", min);
decile = 1;
for (decile = 10; decile < 100; decile += 10)
{
idx = int((decile * n) / 100) + 1;
printf("# %d%% decile = %d\n", decile, item[idx]);
if (decile == 50)
median = item[idx];
}
printf("# Max = %d\n", max);
printf("# Median = %d\n", median);
for (i in count)
{
if (count[i] > count[mode])
mode = i;
}
printf("# Mode = %d\n", mode);
}'
min 和 max 的初始值并不完全科学。它可以说明一个观点。
(这个 1997 年的版本与其 1991 年的前身几乎相同 - 实际上,除了版本信息行是相同的。所以,代码已经有 20 多年的历史了。)