【问题标题】:awk search and calculate standard deviation different resultsawk 搜索和计算标准差不同的结果
【发布时间】:2012-09-07 00:03:36
【问题描述】:

我正在获取 sar 的输出并计算列的标准偏差。我可以使用文件中的单个列成功执行此操作。但是,当我在一个文件中计算同一列时,我将删除标题行和平均行等“坏”行,它给了我一个不同的值。

以下是我正在执行此操作的文件:

/tmp/saru.tmp

# cat /tmp/saru.tmp
Linux 2.6.32-279.el6.x86_64 (progserver)        09/06/2012      _x86_64_        (4 CPU)

11:09:01 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
11:10:01 PM     all      0.01      0.00      0.05      0.01      0.00     99.93
11:11:01 PM     all      0.01      0.00      0.06      0.00      0.00     99.92
11:12:01 PM     all      0.01      0.00      0.05      0.01      0.00     99.93
11:13:01 PM     all      0.01      0.00      0.05      0.00      0.00     99.93
11:14:01 PM     all      0.01      0.00      0.04      0.00      0.00     99.95
11:15:01 PM     all      0.01      0.00      0.06      0.00      0.00     99.92
11:16:01 PM     all      0.01      0.00      2.64      0.01      0.01     97.33
11:17:01 PM     all      0.02      0.00     21.96      0.00      0.08     77.94
11:18:01 PM     all      0.02      0.00     21.99      0.00      0.08     77.91
11:19:01 PM     all      0.02      0.00     22.10      0.00      0.09     77.78
11:20:01 PM     all      0.02      0.00     22.06      0.00      0.09     77.83
11:21:01 PM     all      0.02      0.00     22.10      0.03      0.11     77.75
11:22:01 PM     all      0.01      0.00     21.94      0.00      0.09     77.95
11:23:01 PM     all      0.02      0.00     22.15      0.00      0.10     77.73
11:24:01 PM     all      0.02      0.00     22.02      0.00      0.09     77.87
11:25:01 PM     all      0.02      0.00     22.03      0.00      0.13     77.82
11:26:01 PM     all      0.02      0.00     21.96      0.01      0.14     77.86
11:27:01 PM     all      0.02      0.00     22.00      0.00      0.09     77.89
11:28:01 PM     all      0.02      0.00     21.91      0.00      0.09     77.98
11:29:01 PM     all      0.03      0.00     22.02      0.02      0.08     77.85
11:30:01 PM     all      0.14      0.00     22.23      0.01      0.13     77.48
11:31:01 PM     all      0.02      0.00     22.26      0.00      0.16     77.56
11:32:01 PM     all      0.03      0.00     22.04      0.01      0.10     77.83
Average:        all      0.02      0.00     15.29      0.01      0.07     84.61

/tmp/sarustriped.tmp

# cat /tmp/sarustriped.tmp                              
0.05
0.06
0.05
0.05
0.04
0.06
2.64
21.96
21.99
22.10
22.06
22.10
21.94
22.15
22.02
22.03
21.96
22.00
21.91
22.02
22.23
22.26
22.04

基于/tmp/saru.tmp的计算:

# awk  '$1~/^[01]/ && $6~/^[0-9]/ {sum+=$6; array[NR]=$6} END {for(x=1;x<=NR;x++){sumsq+=((array[x]-(sum/NR))**2);}print sqrt(sumsq/NR)}' /tmp/saru.tmp
10.7126

基于/tmp/sarustriped.tmp的计算(正确的)

# awk '{sum+=$1; array[NR]=$1} END {for(x=1;x<=NR;x++){sumsq+=((array[x]-(sum/NR))**2);}print sqrt(sumsq/NR)}' /tmp/sarustriped.tmp
9.96397

有人可以帮助并告诉我为什么这些结果不同,有没有办法使用单个 awk 命令获得更正的结果。我试图这样做是为了提高性能,因此最好不要使用像 grep 这样的单独命令或其他 awk 命令。

谢谢!

更新

所以我尝试了这个......

awk  '
  $1~/^[01]/ && $6~/^[0-9]/ {
    numrec += 1
    sum    += $6
    array[numrec] = $6
  } 
  END {
    for(x=1; x<=numrec; x++)
      sumsq += ((array[x]-(sum/numrec))^2)
    print sqrt(sumsq/numrec)
  }
' saru.tmp
 

它对我正在使用的 sar -u 输出正常工作。我不明白为什么它不能与其他“列表”一起使用。简而言之,尝试使用 sar -r 第 5 列。它再次给出了错误的答案……输出给出了 1.68891,但实际偏差为 0.107374……这与使用 sar -u 的命令相同。 ....如果您需要我可以提供的文件。只是不确定如何发表新的“完整”评论……所以我只是编辑了旧评论……谢谢!

【问题讨论】:

  • 为了调试这个,打印出一些基本数据:项目的数量和值的总和(以及平均值)。这可能会告诉你有什么不同。如果我不得不猜测,我会怀疑某处有一个空行,所以计数不同。

标签: bash math awk standard-deviation


【解决方案1】:

我认为错误在于您的第一条 awk 行(在 saru.tmp 上运行的行)不会忽略无效行,因此当您使用 NR 进行数学运算时,您的结果取决于跳过的行数。当您删除所有无效/跳过的行时,两个程序的结果是相同的。因此,在第一个命令中,您应该在数学中使用有效行数而不是 NR。

这个怎么样?

awk '
  $1 ~ /^[01]/ && $6~/^[0-9]/ {
    numrec       += 1
    sum          += $6
    array[numrec] = $6
  } 
  END {
    for(x=1; x<=numrec; x++)
      sumsq += (array[x]-(sum/numrec))^2
    print sqrt(sumsq/numrec)
  }
' saru.tmp

【讨论】:

  • 效果很好,仍在尝试解决(数学从来都不擅长)但非常感谢!
  • @user1601716 如果它解决了您的问题,请不要忘记接受答案
  • 简短。尝试使用 sar -r 第 5 列。它再次给出错误答案...输出给出 1.68891 但实际偏差为 0.107374...这与 sar -u 使用的命令相同.....如果你需要我可以提供的文件。只是不确定如何发表新的“完整”评论……谢谢!
  • 请提供新文件。你能检查一下它是否适用于 sar -r 命令的“剥离”版本?
【解决方案2】:

对于这样的调试问题,最简单的技术就是打印一些基本数据。您可以打印项目数、值的总和以及值的平方和(或与平均值的偏差的平方和)。这可能会告诉您两次运行之间有什么不同。有时,在累积数据时打印出正在累积的值可能会有所帮助。如果我不得不猜测,我怀疑你在计算不合适的行(空白或装饰线),所以计数不同(也许总和也不同)。

我有几个(非标准)程序来进行计算。鉴于文件data 中多列输出的 23 条相关行,我运行:

$ colnum -c 6 data | pstats
# Count    = 23
# Sum(x1)  =  3.557200e+02
# Sum(x2)  =  7.785051e+03
# Mean     =  1.546609e+01
# Std Dev  =  1.018790e+01
# Variance =  1.037934e+02
# Min      =  4.000000e-02
# Max      =  2.226000e+01
$

这里的标准差是样本标准差而不是总体标准差;差异是样本除以 (N-1) 和总体除以 N。

【讨论】:

  • 这是我的;我写的。这是一个 Perl 脚本(参数统计)。如果您想要一份副本,请发送电子邮件(请参阅我的个人资料)。
  • 说真的??如果它是您答案的一部分,为什么不上传代码?
  • @foobar:如果你想看看 Perl 的 130 行,你为什么不问?我在一年前的评论中说过如何做到这一点。
  • @JonathanLeffler 从这个意义上说,我认为您的回答并不完整。必须向您发送电子邮件以获取副本对我来说不是一个有效的答案。您的回答是否包含代码(?)我没有收到“给我发送电子邮件......”为什么?当然这是你的代码,你可以放弃也可以不放弃......但在这种情况下,请不要回答。
  • @foobar:当问题是关于awk 时,更多的是不想用难以理解的 Perl 代码混淆答案。我的代码与答案巧合,它解释了如何通过打印适当的值来调试问题。 pwd 教如何钓鱼应该比给鱼更有用。生成基本统计数据的程序必须有很多来源;我当然没有声称我的独特有用——这正是我手头上的东西。
猜你喜欢
  • 2019-05-15
  • 2022-11-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-02
  • 1970-01-01
  • 2021-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多