需要你的帮助,我想根据分钟和平均值和最大值对时间戳进行分组
我的数据如下:
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))
运行此脚本时请注意以下事项
- 该python脚本的名称是test-awk.py
将您的输入保存在文件中并将其命名为 example.js 。将文件路径作为参数传递给此脚本。
我已经使用了标准统计模块找到平均值和最大值。
希望这可以帮助。
答案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]}'