我有数千个带有整数的文本文件。现在,我想知道哪些文本文件包含包含数十个相同或相近数字的长序列。如果数字之间的差异在
5
左右,我认为数字很接近。一般来说,我想用 0%
和 100%
之间的百分比值对文本文件进行评级。 0%
意味着所有数字都相等。 100% 意味着这些数字是完全随机的。我想用概率而不是严格的限制来工作。
最小化输入示例:
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
-> exact 0% as the entire line is one long series of the same number
2 9 21 17 12 2 2 5 4 6 5 6 6 6 7 6 7 5 3 6 6 5 7 7 6 6 5 6 7 6 7 5 7 6 6 6 5 6 6 5 6 78
-> between 0% and 30% as there is a long series with numbers between 5 and 7
20 15 1 2 1 3 2 1 3 18 20 6 12 35 32 35 34 34 34 34 33 34 33 36 44 68 33 32 34 33 53 87
-> between 20% and 40% as there is a series of numbers (32..35), but interrupted by 44+68
12 28 38 44 22 38 16 14 23 45 17 39 29 2 5 15 11 7 2 8 2 14 10 1 14 3 2 2 9 10 4 22 7
-> up to 100% as these numbers are random with out containing series
上述输入线的预期输出范围:
= 0%
> 0% and < 30%
> 10% and < 40%
> 60% and < 100%
目前,我使用百分比标准差:
{
a += $1;
b[++i] = $1
} END {
m = a / NR;
for (i in b) {
d += (b[i] - m) ^ 2
}
print int(sqrt(d / NR) * 100 / m + 0.5)
}
然后我手动检查所有文本文件,结果低于 100%。这在某种程度上是有效的,但绝不是完美的。有没有更好的方法来检测包含相同或接近数字的长序列的文本文件?
就上下文而言,每个文本文件代表一个用户会话,每个数字代表该分钟内的请求数。例如,
4 7 6
表示用户处于活动状态三分钟,第一分钟发出 4 个请求,第二分钟发出 7 个请求,第三分钟发出 6 个请求。一长串相同或接近的数字通常是机器人而不是人类的标志。
我不知道你想要如何计算百分比,但下面的内容,使用任何 awk,将告诉你每个输入行中的每个值有多少个“接近”(即加或减你提供的增量)值出现在一个“长”(即您提供的相邻值的一定长度)存在:
$ cat tst.awk
BEGIN {
delta = (delta == "" ? 2 : delta)
long = (long == "" ? 5 : long)
}
{
numInRange = 0
rangeBeg = rangeEnd = $1
for ( i=1; i<=NF; i++ ) {
valBeg = $i - delta
valEnd = $i + delta
posBeg = (i - long > 1 ? i - long : 1)
posEnd = (i + long < NF ? i + long : NF)
delete maxRange[i]
range = 0
for ( j=posBeg; j<=posEnd; j++ ) {
if ( (valBeg <= $j) && ($j <= valEnd) ) {
range++
maxRange[i] = (range > maxRange[i] ? range : maxRange[i])
}
else {
range = 0
}
}
}
for ( i=1; i<=NF; i++ ) {
printf "%d:%d%s", $i, maxRange[i]-1, (i<NF ? OFS : ORS)
}
}
$ awk -f tst.awk file
4:5 4:6 4:7 4:8 4:9 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:9 4:8 4:7 4:6 4:5
2:0 9:0 21:0 17:0 12:0 2:1 2:1 5:5 4:8 6:7 5:8 6:9 6:10 6:9 7:8 6:7 7:6 5:10 3:1 6:5 6:6 5:10 7:8 7:9 6:10 6:10 5:10 6:10 7:10 6:10 7:10 5:10 7:10 6:10 6:10 6:10 5:10 6:9 6:8 5:7 6:6 5:5
20:0 15:0 1:5 2:6 1:6 3:6 2:6 1:6 3:5 18:1 20:1 6:0 12:0 35:3 32:3 35:5 34:8 34:9 34:10 34:9 33:7 34:7 33:5 36:1 44:0 68:0 33:5 32:5 34:5 33:5 34:5 32:5
12:0 28:0 38:0 44:0 22:0 38:0 16:1 14:1 23:0 45:0 17:0 39:0 29:0 2:0 5:0 15:0 11:0 7:0 2:0 8:0 2:0 14:0 10:0 1:2 14:0 3:2 2:2 2:2 9:1 10:1 4:2 22:0 7:0
希望您可以采用这些值并确定您想要计算的任何“百分比”。