如何在 Perl 中计算一堆数字流的中位数和标准差?

问题描述 投票:0回答:1

在我们的日志文件中,我们存储请求的响应时间。 计算中值响应时间、“75/90/95% 的请求在不到 N 次的时间内得到满足”等数字的最有效方法是什么? (我想我的问题的一个变体是:计算一堆数字流的中位数和标准差的最佳方法是什么)。

我想出的最好办法就是读取所有数字,对它们进行排序,然后挑选出数字,但这看起来真的很愚蠢。 难道就没有更聪明的办法吗?

我们使用 Perl,但任何语言的解决方案可能都会有帮助。

perl statistics logging median
1个回答
0
投票

哎哟!

15 年前,15k 浏览量没有答案? 我来一击!

我很久以前教过统计学课,我们讨论了很多标准差。 我认为最好有一个脚本来快速找到所有值,以防我在课堂上需要它们。 原始脚本比较两个数据集并找到 r 分数、z 分数等。 然后它将所有内容打印在一张大表中。 这只是求平均值和标准差的部分。 可能是最好的方法或者非常接近。 您将需要 CPAN 中的 Math::Complex 来执行 sqrt 函数。 你可以像这样安装。

perl -MCPAN -e 'install Math::Complex'

您可以从 stdin 读取数据,手动用数据填充数组,或者从文件中读取数据,正如我在代码中的 pod 部分中指出的那样。

#!/usr/bin/perl
use Math::Complex;   #for sqrt function

my @dataset_x;
my $x_bar;
my @variation_x;
my @variation_x_squared;
my @x_squared;
my $sum_of_squares_x_deviation_method;
my $sum_of_squares_x_raw_score_method;
my $standard_deviation_x;

#Prompt for dataset from STDIN
#print "\nEnter two datasets:\n";
#print "\nEnter dataset x separated by spaces: ";
#my $dataset = <STDIN>;
#chomp $dataset;

=begin
you could grab the data from a file and put it into the dataset array if you wanted
something like (from command line)
$perl standardDeviation.pl dataFile.txt

And in the code, put the data into the dataset something like
while(<>){
   do some formatting or something with $_;
   push(@dataset_x, $_);
}

=end

=cut

#Hand enter dataset here
$dataset = "49 34 35 43 61 42 54 23 21 56";
my @dataset_x = split(/\s/,$dataset);

#find average first
$x_bar = 0;
for(my $j = 0; $j < @dataset_x; $j++){
  $x_bar=$x_bar + $dataset_x[$j];
}
$x_bar = $x_bar / @dataset_x;

#calculate the different columns, each in its own array
for($j = 0; $j < @dataset_x; $j++){
  $variation_x[$j] = $dataset_x[$j] - $x_bar;
  $variation_x_squared[$j] = $variation_x[$j] * $variation_x[$j];
  $x_squared[$j] = $dataset_x[$j] * $dataset_x[$j];
}

#find the sum of squares and standard deviation
$sum_of_squares_x_deviation_method = &sum(@variation_x_squared);
$sum_of_squares_x_raw_score_method = &sum(@x_squared) - ((&sum(@dataset_x)**2) / @dataset_x);
$standard_deviation_x = sqrt( $sum_of_squares_x_deviation_method / @dataset_x );

#Show result
my $print_dataset_x = join(" ", @dataset_x);
print  "\"$print_dataset_x\"\n";
print "Average is $x_bar\n";
print "Standard deviation (deviation method) is $standard_deviation_x\n";
print "\n";

#function to sum all values in an array
sub sum{
  my $tmp;
  $tmp = 0;
  for(my $i=0;$i < @_; $i++){
    $tmp = $tmp + @_[$i];
  }
  $tmp;
}

输出看起来像这样

$perl standardDeviation.pl
"49 34 35 43 61 42 54 23 21 56"
Average is 41.8
Standard deviation (deviation method) is 12.9058126439213
© www.soinside.com 2019 - 2024. All rights reserved.