计算标准偏差


19

挑战

给定一个数字列表,计算该列表的总体标准差。

使用以下公式计算总体标准偏差:

输入项

输入将以任何格式(列表,字符串等)显示整数列表。一些例子:

56,54,89,87
67,54,86,67

数字将始终是整数。

输入将输入到STDIN或函数参数。

输出量

输出必须是浮点数。

规则

您可以使用内置函数来查找标准偏差。

您的答案可以是完整程序或功能。

例子

10035, 436844, 42463, 44774 => 175656.78441352615

45,67,32,98,11,3 => 32.530327730015607

1,1,1,1,1,1 => 0.0

获奖

以最短的程序或函数为准。

排行榜


1
您的意思是输出必须是浮点数或整数?
Mutador

3
我认为大多数内置标准差函数都会计算样本标准差。
Mutador

如果输入列表为空怎么办?175656.78441352615结果对我来说是175656.78441352614
RosLuP

@RosLuP您不必担心
Beta Decay

1
@ a13a22按PPCG的标准规则,你通过函数的参数都很好采取输入
β衰变

Answers:


18

,3

.sk

.s是标准偏差,k以形式解析输入{1,2,3}


标准偏差使用什么公式?我找不到它供他参考。
瑕疵的

@flawr这是底部的图表
Conor O'Brien 2015年

@CᴏɴᴏʀO'Bʀɪᴇɴ我看到了,但是没有给出公式。
瑕疵的

@flawr哦,我明白了。如果存在这种情况,那么也许取决于解释器。
Conor O'Brien 2015年

2
@CᴏɴᴏʀO'Bʀɪᴇɴ我发现它在这里上线493,它似乎是确定!
瑕疵的

11

Mathematica,24个 22字节

不错,Mathematica有一个内置的StandardDevi...oh ...,它可以计算样本标准偏差,而不是总体标准偏差。

但是,如果我们使用Variance...哦,同样的交易该怎么办。

但是还有另一个相关的内置函数:

CentralMoment[#,2]^.5&

好极了。:)

这也适用于22个字节:

Mean[(#-Mean@#)^2]^.5&

这是27:

N@RootMeanSquare[#-Mean@#]&

10

八度,14字节

g=@(a)std(a,1)

ideone上尝试一下。


2
您可以删除两个字节,g=因为函数句柄不需要名称即可成为有效提交。
Alex A.

10

kdb +,3个字节

dev

APL派生工具之一必须具有内置功能。

测试运行

q)dev 56, 54, 89, 87
16.53028
q)f:dev
q)f 10035, 436844, 42463, 44774
175656.8
q)f 45,67,32,98,11,3
32.53033

8

Dyalog APL,24 23 21 20 19 17字节

*∘.5∘M×⍨-M×M←+/÷≢

这定义了一个未命名的单子函数链,它等效于以下函数。

{.5*⍨M(×⍨⍵)-M⍵×(M←{(+/⍵)÷≢⍵})⍵}

TryAPL上在线尝试

怎么运行的

该代码由几列火车组成。

M←+/÷≢

这定义了一个三元组的3列(fork)M,它对正确的参数执行+/(所有元素的总和)和(长度),然后÷对结果应用(除法),返回输入的算术平均值。

M×M

这是适用另一个叉M于右参数,反复进行该第二次,并应用×(产品)的结果,返回μ 2

×⍨-(M×M)

这是另一个分叉,它如前所述计算算术平均值的平方,将×⍨(乘积本身)应用于正确的自变量,最后将-(差)应用于结果。

对于输入(X 1,...,X Ñ,此函数返回(X 1 - μ 2,...,X ñ - μ 2

*∘.5∘M

该组合函数将应用于M右参数*∘.5。后者使用正确的参数currying将地图输入a应用于的a*0.5平方根a

(*∘.5∘M)(×⍨-(M×M))

最后,我们得到了该单调2列(上),它首先应用右函数,然后将左函数应用到其结果,按如下方式计算标准偏差。

formula


5

R,41 40 39 36 30 28字节

感谢烧杯Alex A.MickyT的大量字节。

cat(sd(c(v=scan(),mean(v))))   

旧密码

v=scan();n=length(v);sd(v)/(n/(n-1))**0.5
m=scan();cat(sqrt(sum(mean((m-mean(m))^2))))
m=scan();cat(mean((m-mean(m))^2)^.5) 

这将产生总体标准偏差。


1
我不知道R,但是有可能用数组的平均值来扩充输入数组吗?似乎可能会更短。
烧杯

1
在此站点上,除非问题明确允许,否则我们通常无法假定REPL环境。因此,在这种情况下,您需要cat用于打印到控制台。
Alex A.

1
另外,R ^用于取幂,比短一个字节**
Alex A.

1
您不需要对平均值求和,因为它mean返回标量;sum没有效果。36个字节:x=scan();cat(mean((x-mean(x))^2)^.5)
Alex A.

1
@AndréMuta表示歉意,当我对其进行测试时,我的X随处可见。
MickyT 2015年

5

Pyth,20 19 17 13字节

@.O^R2-R.OQQ2

感谢@FryAmTheEggman打高尔夫球4个字节!

在线尝试。

怎么运行的

        .OQ    Compute the arithmetic mean of the input (Q).
      -R   Q   Subtract the arithmetic mean of all elements of Q.
   ^R2         Square each resulting difference.
 .O            Compute the arithmetic mean of the squared differences.
@           2  Apply square root.

我喜欢Pyth程序的分解看起来像是歪斜的抛物线。
Conor O'Brien 2015年

5

CJam,24 22 21字节

q~_,_@_:+d@/f-:mh\mq/

感谢@aditsu打高尔夫球1个字节!

CJam解释器中在线尝试。

怎么运行的

q~                    e# Read all input and evaluate it.
  _,                  e# Copy the array and push its length.
    _@                e# Copy the length and rotate the array on top.
      _:+d            e# Copy the array and compute its sum. Cast to Double.
          @/          e# Rotate the length on top and divide the sum by it.
            f-        e# Subtract the result (μ) from the array's elements.
              :mh     e# Reduce by hypotenuse.
                      e# a b mh -> sqrt(a^2 + b^2)
                      e# sqrt(a^2 + b^2) c mh -> sqrt(sqrt(a^2 + b^2)^2 + c^2)
                      e#                           = sqrt(a^2 + b^2 + c^2)
                      e# ⋮
                 \mq/ e# Divide the result by the square root of the length.

我认为您可以将长度仅转换为两倍
-aditsu

@aditsu当然。谢谢!
丹尼斯2015年

5
:mh是天才btw :)
aditsu

2
Reduce by hypotenuse.不是每天都看到的东西。
lirtosiast

4

APL,24字节

{.5*⍨+/(2*⍨⍵-+/⍵÷≢⍵)÷≢⍵}

与方法略有不同 Dennis的Dyalog APL解决方案。这应该适用于任何APL实现。

这将创建一个未命名的单调函数,该函数将向量(x - µ2计算2*⍨⍵-+/⍵÷≢⍵,除以N÷≢⍵),使用取该向量的总和+/,然后取平方根(.5*⍨)。

在线尝试


并非所有的APL实现支持{DFN和}。然而,每个版本支持R←F Y R←(+/((Y-+/Y÷⍴Y)*2)÷⍴Y)*.5
亚当

4

朱莉娅,26 19字节

x->std([x;mean(x)])

这将创建一个未命名函数,该函数接受数组并返回浮点数。

松散,我猜:

function f(x::Array{Int,1})
    # Return the sample standard deviation (denominator N-1) of
    # the input with the mean of the input appended to the end.
    # This corrects the denominator to N without affecting the
    # mean.
    std([x; mean(x)])
end

4

TI-BASIC,7个字节

stdDev(augment(Ans,{mean(Ans

我从这里借用了从样本标准差中获取总体标准差的算法。

没有的话,我能找到的最短解决方案augment(是9个字节:

stdDev(Ans√(1-1/dim(Ans

我同意AndréMuta的观点,这不会产生所需的结果,请参见此处。
瑕疵的

1
TI的内置函数@AndréMuta@flawr stdDev(计算样本SD;stdDev(augment(Ans,{mean(Ans计算总体SD。在您链接到的页面上。
lirtosiast 2015年

3

Haskell, 61 bytes

d n=1/sum(n>>[1])
f a=sqrt$d a*sum(map((^2).(-)(d a*sum a))a)

Straightforward, except maybe my custom length function sum(n>>[1]) to trick Haskell's strict type system.


You can use sum(1<$n) and <$> for map.
Laikoni

It just occurred to me that those functions might not be present because of an older GHC version at the time of this answer, but according to this tip they were introduced to prelude in March 2015, and the site policy has changed anyway to allow newer language features.
Laikoni

3

Python 3.4+, 30 bytes

from statistics import*;pstdev

Imports the builtin function pstdev, e.g.

>>> pstdev([56,54,89,87])
16.53027525481654

I think just pstdev after the first line is ok? I believe xnor did that a while ago with sum. It sort of makes sense wrt how anonymous lambdas would be used i.e. p=pstdev or map(pstdev, [...])
FryAmTheEggman

I was going to say the same thing. Meta posts seem to support just putting a function literal.
xnor

I think you still need to write the literal pstdev though, like from statistics import*;pstdev. Otherwise, this could be any function from that library.
xnor

@xnor Edited. tbh I'm not really sure about the ruling on these situations...
Sp3000

Maybe a meta question would be helpful? :)
Beta Decay

2

JavaScript (ES6), 73 bytes

a=>Math.sqrt(a.reduce((b,c)=>b+(d=c-eval(a.join`+`)/(l=a.length))*d,0)/l)

@BetaDecay Regarding precision of the output? My original actually didn't have that correct, and I fixed it right after, only to discover floating point was ok hehe... So is it good now as it is?
Mwr247

Yeah that's fine :)
Beta Decay

7
Psst... you can shave off 5 bytes by using this summing method eval(a.join`+`) instead of a.reduce((e,f)=>e+f)
George Reith

@GeorgeReith Nice trick! I'm going to have to remember that one for later...
Mwr247

2

Jelly, non-competing

11 bytes This answer is non-competing, since it uses a language that postdates the challenge.

S÷L
Dz_²ÇN½

This is a direct translation of my APL answer to Jelly. Try it online!

How it works

S÷L        Helper link. Argument: z (vector)

S          Compute the sum of z.
  L        Compute the length of z.
 ÷         Divide the former by the latter.
           This computes the mean of z.

Dz_²ÇN½    Main link. Argument: z (vector)

Ç          Apply the previous link, i.e., compute the mean of z.
 ²         Square the mean.
   ²       Square all number in z.
  _        Subtract each squared number from the squared mean.
    Ç      Take the mean of the resulting vector.
     N     Multiply it by -1.
      ½    Take the square root of the result.


1

Simplex v.0.5, 43 bytes

Just 'cuz. I really need to golf this one more byte.

t[@u@RvR]lR1RD@wA@T@{j@@SR2ERpR}u@vR@TR1UEo   
t[      ]                                     ~~ Applies inner function to entire strip (left-to-right)
  @                                           ~~ Copies current value to register
   u                                          ~~ Goes up a strip level
    @                                         ~~ Dumps the register on the current byte
     R                                        ~~ Proceeds right (s1)
      v                                       ~~ Goes back down
       R                                      ~~ Proceeds right (s0)
                                              ~~ Go right until an empty byte is found
         lR1RD                                ~~ Push length, 1, and divide.
              @                               ~~ Store result in register (1/N)
               wA                             ~~ Applies A (add) to each byte, (right-to-left)
                 @T@                          ~~ Puts 1/N down, multiplies it, and copies it to the register
                    {          }              ~~ Repeats until a zero-byte is met
                     j@@                      ~~ inserts a new byte and places register on it
                        SR                    ~~ Subtract it from the current byte and moves right
                          2E                  ~~ Squares result
                            RpR               ~~ Moves to the recently-created cell, deletes it, and continues
                                u@v           ~~ takes 1/N again into register
                                   R@T        ~~ multiplies it by the new sum
                                      R1UE    ~~ takes the square root of previous
                                          o   ~~ output as number

1

Prolog (SWI), 119 bytes

Code:

q(U,X,A):-A is(X-U)^2.
p(L):-sumlist(L,S),length(L,I),U is S/I,maplist(q(U),L,A),sumlist(A,B),C is sqrt(B/I),write(C).

Explanation:

q(U,X,A):-A is(X-U)^2.   % calc squared difference of X and U
p(L):-sumlist(L,S),      % sum input list
      length(L,I),       % length of input list
      U is S/I,          % set U to the mean value of input list
      maplist(q(U),L,A), % set A to the list of squared differences of input and mean
      sumlist(A,B),      % sum squared differences list
      C is sqrt(B/I),    % divide sum of squares by length of list
      write(C).          % print answer

Example:

p([10035, 436844, 42463, 44774]).
175656.78441352615

Try it out online here


1

Perl5, 39 38


 16 for the script
+22 for the M switch
+ 1 for the E switch
=39

perl -MStatistics::Lite=:all -E"say stddevp@ARGV" .1 .2 300

Tested in Strawberry 5.20.2.


Oh, but then I realized that you said our answers can be functions instead of programs. In that case,

{use Statistics::Lite":all";stddevp@_}

has just 38. Tested in Strawberry 5.20.2 as

print sub{use Statistics::Lite":all";stddevp@_}->( .1, .2, 300)

0

Python, 57 bytes

lambda l:(sum((x-sum(l)/len(l))**2for x in l)/len(l))**.5

Takes input as a list

Thanks @xnor


I think you can do .5 in place of 0.5 to save a byte. Also do you mean len(x) instead of len(l)?
Alex A.

@AlexA. Uhh, no I don't think so...
Beta Decay

1
Sorry, got confused. Disregard the x and l nonsense. But you can still do .5 to save a byte.
Alex A.

1
@BetaDecay It's shorter to use a list-comp than to map a lambda: sum((x-sum(l)/len(l))**2for x in l).
xnor

1
A different formulation gave the same length: lambda l:(sum(x*x*len(l)for x in l)-sum(l)**2)**.5/len(l).
xnor

0

PowerShell, 122

:\>type stddev.ps1
$y=0;$z=$args -split",";$a=($z|?{$_});$c=$a.Count;$a|%{$y+=$_};$b=$y/$c;$a|%{$x+
=(($_-$b)*($_-$b))/$c};[math]::pow($x,0.5)

explanation

<#
$y=0                            init
$z=$args -split","              split delim ,
$a=($z|? {$_})                  remove empty items
$c=$a.Count                     count items
$a|%{$y+=$_}                    sum
$b=$y/$c                        average
$a|%{$x+=(($_-$b)*($_-$b))/$c}  sum of squares/count
[math]::pow($x,0.5)             result
#>

result

:\>powershell -nologo -f stddev.ps1 45,67,32,98,11,3
32.5303277300156

:\>powershell -nologo -f stddev.ps1 45,  67,32,98,11,3
32.5303277300156

:\>powershell -nologo -f stddev.ps1 45,  67,32, 98 ,11,3
32.5303277300156

:\>powershell -nologo -f stddev.ps1 10035, 436844, 42463, 44774
175656.784413526

:\>powershell -nologo -f stddev.ps1 1,1,1,1,1,1
0

0

Fortran, 138 bytes

Just a straightforward implementation of the equation in Fortran:

double precision function std(x)
integer,dimension(:),intent(in) :: x
std = norm2(dble(x-sum(x)/size(x)))/sqrt(dble(size(x)))
end function

0

SmileBASIC, 105 bytes (as a function)

I just noticed it's allowed to be a function. Whoops, that reduces my answer dramatically. This defines a function S which takes an array and returns the population standard deviation. Go read the other one for an explanation, but skip the parsing part. I don't want to do it again.

DEF S(L)N=LEN(L)FOR I=0TO N-1U=U+L[I]NEXT
U=1/N*U FOR I=0TO N-1T=T+POW(L[I]-U,2)NEXT RETURN SQR(1/N*T)END

As a program, 212 bytes

Unfortunately, I have to take the input list as a string and parse it myself. This adds over 100 bytes to the answer, so if some input format other than a comma-separated list is allowed I'd be glad to hear it. Also note that because VAL is buggy, having a space before the comma or trailing the string breaks the program. After the comma or at the start of the string is fine.

DIM L[0]LINPUT L$@L I=INSTR(O,L$,",")IF I>-1THEN PUSH L,VAL(MID$(L$,O,I-O))O=I+1GOTO@L ELSE PUSH L,VAL(MID$(L$,O,LEN(L$)-O))
N=LEN(L)FOR I=0TO N-1U=U+L[I]NEXT
U=1/N*U FOR I=0TO N-1T=T+POW(L[I]-U,2)NEXT?SQR(1/N*T)

Ungolfed and explained:

DIM L[0]  'define our array
LINPUT L$ 'grab string from input

'parse list
'could've used something cleaner, like a REPEAT, but this was shorter
@L
I=INSTR(O,L$,",")                 'find next comma
IF I>-1 THEN                      'we have a comma
 PUSH L,VAL(MID$(L$,O,I-O))       'get substring of number, parse & store
 O=I+1                            'set next search location
 GOTO @L                          'go again
ELSE                              'we don't have a comma
 PUSH L,VAL(MID$(L$,O,LEN(L$)-O)) 'eat rest of string, parse & store
ENDIF                             'end

N=LEN(L) 'how many numbers we have

'find U
'sum all of the numbers, mult by 1/N
FOR I=0 TO N-1
 U=U+L[I]
NEXT
U=1/N*U

'calculate our popstdev
'sum(pow(x-u,2))
FOR I=0 TO N-1
 T=T+POW(L[I]-U,2)
NEXT
PRINT SQR(1/N*T) 'sqrt(1/n*sum)

0

Axiom, 137 bytes

m(a:List Float):Complex Float==(#a=0=>%i;reduce(+,a)/#a)
s(a:List Float):Complex Float==(#a=0=>%i;n:=m(a);sqrt(m([(x-n)^2 for x in a])))

The function m() would return the mean of the list in input. Both the functions on error return %i the imaginary constant sqrt(-1). Code for test and results. [but the result if it is ok, it is the real part of one complex number]

(6) -> s([45,67,32,98,11,3])
   (6)  32.5303277300 15604966

(7) -> s([10035,436844,42463,44774])
   (7)  175656.7844135261 4035

(8) -> s([1,1,1,1,1,1])
   (8)  0.0


0

Pyt, 13 bytes

←Đ↔Ł↔е-²Ʃ⇹/√

Implements the formula for standard deviation

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.