如何根据团体时间计算平均值和最大值

如何根据团体时间计算平均值和最大值

需要你的帮助,我想根据分钟和平均值和最大值对时间戳进行分组

我的数据如下:

2019-12-27 12:01:00,047 3
2019-12-27 12:01:00,079 34
2019-12-27 12:02:00,091 4
2019-12-27 12:02:00,091 5
2019-12-27 12:03:00,099 3
2019-12-27 12:04:00,101 8

我的预期结果:

timestamp        average max
2019-12-27 12:01 18.5     34
2019-12-27 12:02 4.5      5 
2019-12-27 12:03 3        3
2019-12-27 12:04 8        8

你能帮我解决上述问题吗,谢谢帮助

答案1

一个简单的 Python 程序就可以完成这个任务。

import sys
from statistics import mean
time_to_value_dict = {}
# usage guide : python3 test-awk.py /Users/a/Desktop/example.js
with open(sys.argv[1]) as f:
    for line in f:
        parts = line.split()
        second_field = parts[1]
        third_field = int(parts[2])
        # to take the required value from the second field by slicing the string
        trimmed_key = second_field[0:5]
        final_key = parts[0] + " " + trimmed_key
        arr = time_to_value_dict.get(final_key,[])
        arr.append(third_field)
        time_to_value_dict[final_key] = arr
    print("timestamp        average          max")
    list_to_print = []
    for item in time_to_value_dict:
        value_from_dict = time_to_value_dict.get(item)
        average_val = mean(value_from_dict)
        max_val = max(value_from_dict)
        temp_list = []
        temp_list.append(item)
        temp_list.append(str(average_val))
        temp_list.append(str(max_val))
        list_to_print.append(temp_list)
        temp_list = []
    col_width = max(len(word) for row in list_to_print for word in row) + 1  # padding
    for row in list_to_print:
        print ("".join(word.ljust(col_width) for word in row))

运行此脚本时请注意以下事项

  1. 该python脚本的名称是test-awk.py
  2. 将您的输入保存在文件中并将其命名为 example.js 。将文件路径作为参数传递给此脚本。

  3. 我已经使用了标准统计模块找到平均值和最大值。

希望这可以帮助。

答案2

Perl 来救援!

< data.txt perl -lne '
    ($time, $num) = /(.*),.* (.*)/;
    if ($time ne $previous_time && $count) {
        print join " ", $previous_time, $sum / $count, $max;
        ($sum, $count, $max) = (0, 0, 0);
    }
    $max = $num if $num > $max;
    $sum += $num;
    ++$count;
    $previous_time = $time;
    END { print join " ", $previous_time, $sum / $count, $max; }'
  • -n逐行读取输入
  • -l从输入中删除换行符并将其添加到输入中
  • 如果不带逗号后部分的时间与前一个时间不同,我们将报告前一个时间的平均值和最大值,并重置保存它们的变量。我们始终填充最大值、总和、计数和前一个时间。

这仅在同一时间的日期相邻时才有效。如果不是,则需要一个哈希来收集每个时间戳的数据:

< data.txt perl -MList::Util=max,sum -lne '
    ($time,$num) = /(.*),.* (.*)/;
    push @{ $by_time{$time} }, $num;
    END { print "timestamp average max";
          for (sort keys %by_time) {
              @nums = @{ $by_time{$_} };
              print join " ", $_, sum(@nums) / @nums, max(@nums);
          }
    }'
  • -M加载模块,参见列表::实用程序对于特定的一个
  • 每次不带逗号后的部分都用作哈希表中的键%by_time。我们存储每个键的数组引用,该数组包含所有数字。

答案3

使用 awk 的解决方案

awk -F'[: ,]' '
{
        for (i = 0; i <= 59; i++) {
                sprintf("%02d", i)
                if ($3 == i) {
                        line[i] = $1 " " $2 ":" $3
                        count[i]++
                        sum[i] += $6
                        max[i] = max[i] < $6 ? $6 : max[i]
                        next
                }
        }
}

END {
        print "timestamp", "average", "max"
        for (i in count) {
                print line[i], sum[i] / count[i], max[i]
        }
}' file

输出未格式化,可以用 来完成printf

(原始的命令行想法,使用 -o 选项进行漂亮的打印)

awk -F'[: ,]' '{for (i=0;i<=59;i++) {sprintf("%02d",i); if ($3 == i) {line[i]=$1" "$2":"$3;count[i]++;sum[i]+=$6;max[i]=max[i]<$6?$6:max[i];next};};};END{print "timestamp","average","max";for (i in count) print line[i],sum[i]/count[i],max[i]}'

相关内容