使用perl查找中值、模式、标准差?
我有一个数字数组。计算数据集的中值、模式和标准偏差的最简单方法是什么?使用perl查找中值、模式、标准差?,perl,statistics,Perl,Statistics,我有一个数字数组。计算数据集的中值、模式和标准偏差的最简单方法是什么? 根据您需要的深度,erickb的答案可能有效。然而,对于Perl中的数字功能,存在以下问题。您可以使用函数创建一个piddle(包含数据的对象)。从那里,您可以使用上的操作来进行所需的统计 编辑:环顾四周,我发现两个函数调用完全满足您的需要。提供一个皮德尔维度的统计信息,而stats在整个皮德尔维度上提供相同的统计信息 my $piddle = pdl @data; my ($mean,$prms,$median,$
stats
在整个皮德尔维度上提供相同的统计信息
my $piddle = pdl @data;
my ($mean,$prms,$median,$min,$max,$adev,$rms) = statsover $piddle;
#/usr/bin/perl
#
#标准偏差-图N、最小值、最大值、中值、模式、平均值和标准偏差
#
#拉出输入中的所有实数
#流式处理并对其运行标准计算。
#根据需要,它们可能与其他测试混合使用
#不在相同或不同的线路上,以及
#可以是科学概念(avagadro=6.02e23)。
#他们也承认领先+或-。
#
#汤姆克里斯汀森
# tchrist@perl.com
严格使用;
使用警告;
使用列表::Util qw;
按编号分组{
如果($a<$b){-1}elsif($a>$b){1}else{0}
}
#
我的$number\u rx=qr{
#前导符号,正号或负号
(?: [+-] ? )
#尾数
(?= [0123456789.] )
(?:
#“N”或“N”或“N.N”
(?:
(?: [0123456789] + )
(?:
(?: [.] )
(?: [0123456789] * )
) ?
|
#“.N”,无前导数字
(?:
(?: [.] )
(?: [0123456789] + )
)
)
)
#横坐标
(?:
(?:[Ee])
(?:
(?: [+-] ? )
(?: [0123456789] + )
)
|
)
}x;
我的$n=0;
我的$sum=0;
我的@values=();
我的%SEED=();
而(){
而(/($number_rx)/g){
$n++;
我的$num=0+$1;#0+是这样的,所以交替形式的数字计数相同
$sum+=$num;
推送@values,$num;
$seen{$num}++;
}
}
如果$n==0,则为“无值”;
我的$mean=$sum/$n;
我的$sqsum=0;
for(@值){
$sqsum+=($\**2);
}
$sqsum/=$n;
$sqsum-=($mean**2);
我的$stdev=sqrt($sqsum);
我的$max\u seen\u count=最大值%seen;
我的@modes=grep{$seen{$\u}==max\u seen\u count}键%seen;
我的$mode=@modes==1
? $模式[0]
:“(“.join(“,”,@modes)。”);
$mode.='@'$最大可见计数;
我的美元中位数;
我的$mid=int@values/2;
my@sorted_values=按_编号@values排序;
如果(@值%2){
$median=$sorted_值[$mid];
}否则{
$median=($sorted_值[$mid-1]+$sorted_值[$mid])/2;
}
我的$min=min@值;
我的$max=max@值;
printf“n是%d,min是%g,max是%g\n”,$n,$min,$max;
printf“模式为%s,中值为%g,平均值为%g,标准差为%g\n”,
$mode,$median,$mean,$stdev;
事实上,我以前没有听说过PDL,我想因为我所做的大部分工作都是系统管理工具开发之类的。这真的很酷,谢谢你的提示。@BadFileMagic,在看到一个关于NumPy/SciPy的演讲后,我真的很沮丧,因为我认为这最终意味着我不得不离开Perl,转而使用Python。然后我找到了PDL。很好,以前从没听说过。看起来不可思议!对于某些“更好”的定义来说,这比sub by_number{return$a$b}
好吗?my@sorted_values=sort{$a$b}@values有什么问题代码>?@hepcat72这是个好问题,真的。我不再记得我为什么这么做了。为什么在那个模块中没有Statistics::Basic::Max
或Statistics::Basic::Min
?因为它们在内核中的List::Util中。
#!/usr/bin/perl
#
# stdev - figure N, min, max, median, mode, mean, & std deviation
#
# pull out all the real numbers in the input
# stream and run standard calculations on them.
# they may be intermixed with other test, need
# not be on the same or different lines, and
# can be in scientific notion (avagadro=6.02e23).
# they also admit a leading + or -.
#
# Tom Christiansen
# tchrist@perl.com
use strict;
use warnings;
use List::Util qw< min max >;
sub by_number {
if ($a < $b){ -1 } elsif ($a > $b) { 1 } else { 0 }
}
#
my $number_rx = qr{
# leading sign, positive or negative
(?: [+-] ? )
# mantissa
(?= [0123456789.] )
(?:
# "N" or "N." or "N.N"
(?:
(?: [0123456789] + )
(?:
(?: [.] )
(?: [0123456789] * )
) ?
|
# ".N", no leading digits
(?:
(?: [.] )
(?: [0123456789] + )
)
)
)
# abscissa
(?:
(?: [Ee] )
(?:
(?: [+-] ? )
(?: [0123456789] + )
)
|
)
}x;
my $n = 0;
my $sum = 0;
my @values = ();
my %seen = ();
while (<>) {
while (/($number_rx)/g) {
$n++;
my $num = 0 + $1; # 0+ is so numbers in alternate form count as same
$sum += $num;
push @values, $num;
$seen{$num}++;
}
}
die "no values" if $n == 0;
my $mean = $sum / $n;
my $sqsum = 0;
for (@values) {
$sqsum += ( $_ ** 2 );
}
$sqsum /= $n;
$sqsum -= ( $mean ** 2 );
my $stdev = sqrt($sqsum);
my $max_seen_count = max values %seen;
my @modes = grep { $seen{$_} == $max_seen_count } keys %seen;
my $mode = @modes == 1
? $modes[0]
: "(" . join(", ", @modes) . ")";
$mode .= ' @ ' . $max_seen_count;
my $median;
my $mid = int @values/2;
my @sorted_values = sort by_number @values;
if (@values % 2) {
$median = $sorted_values[ $mid ];
} else {
$median = ($sorted_values[$mid-1] + $sorted_values[$mid])/2;
}
my $min = min @values;
my $max = max @values;
printf "n is %d, min is %g, max is %g\n", $n, $min, $max;
printf "mode is %s, median is %g, mean is %g, stdev is %g\n",
$mode, $median, $mean, $stdev;