![如何计算文件中第二个字段的平均值?](https://linux22.com/image/1015942/%E5%A6%82%E4%BD%95%E8%AE%A1%E7%AE%97%E6%96%87%E4%BB%B6%E4%B8%AD%E7%AC%AC%E4%BA%8C%E4%B8%AA%E5%AD%97%E6%AE%B5%E7%9A%84%E5%B9%B3%E5%9D%87%E5%80%BC%EF%BC%9F.png)
我有一个文件,它由两个字段组成。第一个字段格式是“%FT%T”。
样本数据:
2019-01-01T00:00:00 4.8
2019-01-01T01:00:00 5.1
2019-01-01T02:00:00 5.4
2019-01-01T03:00:00 5.7
2019-01-01T04:00:00 5.8
2019-01-01T05:00:00 5.4
2019-01-01T06:00:00 5
2019-01-01T07:00:00 4.4
2019-01-01T08:00:00 3.8
2019-01-01T09:00:00 3.7
2019-01-01T10:00:00 3.8
2019-01-01T11:00:00 4.1
2019-01-01T12:00:00 5
2019-01-01T13:00:00 6.7
2019-01-01T14:00:00 8.4
2019-01-01T15:00:00 9.1
2019-01-01T16:00:00 8.6
2019-01-01T17:00:00 8.5
2019-01-01T18:00:00 8.6
2019-01-01T19:00:00 8.1
2019-01-01T20:00:00 8
2019-01-01T21:00:00 6.9
2019-01-01T22:00:00 5.6
2019-01-01T23:00:00 5.2
2019-01-02T00:00:00 5.2
2019-01-02T01:00:00 5.3
2019-01-02T02:00:00 5.8
2019-01-02T03:00:00 6
2019-01-02T04:00:00 5.7
2019-01-02T05:00:00 5.4
2019-01-02T06:00:00 5.7
2019-01-02T07:00:00 5.3
2019-01-02T08:00:00 4.8
2019-01-02T09:00:00 4.3
2019-01-02T10:00:00 3.6
2019-01-02T11:00:00 2.8
2019-01-02T12:00:00 3.2
2019-01-02T13:00:00 4.2
2019-01-02T14:00:00 4.9
2019-01-02T15:00:00 5.4
2019-01-02T16:00:00 5.9
2019-01-02T17:00:00 6.5
2019-01-02T18:00:00 6.7
2019-01-02T19:00:00 7.1
2019-01-02T20:00:00 5.7
2019-01-02T21:00:00 4.4
2019-01-02T22:00:00 4.1
2019-01-02T23:00:00 3.8
2019-01-03T00:00:00 4
2019-01-03T01:00:00 3.5
2019-01-03T02:00:00 3.6
2019-01-03T03:00:00 4
2019-01-03T04:00:00 4.2
2019-01-03T05:00:00 3.9
2019-01-03T06:00:00 3.7
2019-01-03T07:00:00 3.8
2019-01-03T08:00:00 3.7
2019-01-03T09:00:00 3.7
2019-01-03T10:00:00 4
2019-01-03T11:00:00 4.7
2019-01-03T12:00:00 5.4
2019-01-03T13:00:00 6.5
2019-01-03T14:00:00 7.6
2019-01-03T15:00:00 7.7
2019-01-03T16:00:00 7.3
2019-01-03T17:00:00 7.4
2019-01-03T18:00:00 8
2019-01-03T19:00:00 8.5
2019-01-03T20:00:00 8.1
2019-01-03T21:00:00 6.5
2019-01-03T22:00:00 5.6
2019-01-03T23:00:00 5.6
我想计算第二列的每日平均值。
输出应如下所示...
01-01-2019 6.1
02-01-2019 5.1
03-01-2019 5.5
答案1
一种 awk 方法:
$ awk '{
date=substr($1,1,10);
tot[date]+=$2;
num[date]++
}
END{
for(date in tot){
printf "%s %.1f\n", date,tot[date]/num[date]
}
}' file
2019-01-01 6.1
2019-01-02 5.1
2019-01-03 5.5
答案2
使用磨坊主
$ mlr --nidx --repifs put '
$1 = strftime(strptime($1,"%FT%T"),"%d-%m-%Y")
' then stats1 -a mean -f 2 -g 1 file
01-01-2019 6.070833
02-01-2019 5.075000
03-01-2019 5.458333
格式化结果似乎是 Miller 有点缺乏的一个领域,所以如果您需要,我建议通过numfmt
ex 传输结果。
$ mlr --nidx --repifs put '
$1 = strftime(strptime($1,"%FT%T"),"%d-%m-%Y")
' then stats1 -a mean -f 2 -g 1 file | numfmt --field=2 --format='%.1f'
01-01-2019 6.1
02-01-2019 5.1
03-01-2019 5.5
或者,使用足够新的 GNU awk 版本并使用日期的纪元时间mktime
来索引sum
和数组:count
gawk '
{
split($1,dt,"[-T:]");
k = mktime(sprintf("%04d %02d %02d 00 00 00", dt[1], dt[2], dt[3]));
sum[k] += $2; count[k] += 1;
}
END {
PROCINFO["sorted_in"] = "@ind_num_asc";
for(k in count) printf "%s %.1f\n", strftime("%d-%m-%Y",k), sum[k]/count[k];
}
' file
另一种替代方法是使用基于 Python 的csvsql
/ :csvformat
csvkit
$ csvsql -d ' ' -HS --query '
SELECT strftime("%d-%m-%Y",date(a)) AS [Day], round(avg(b),1) AS [Avg] FROM file GROUP BY date(a)
' file | csvformat -T
/usr/lib/python3/dist-packages/agate/table/from_csv.py:88: RuntimeWarning: Column names not specified. "('a', 'b')" will be used as names.
Day Avg
01-01-2019 6.1
02-01-2019 5.1
03-01-2019 5.5