สร้างมาตรฐานตัวอย่าง (คำนวณคะแนน z)


14

ได้รับรายชื่อของลอยหมายเลขจุดมาตรฐานมัน

รายละเอียด

  • รายการx1,x2,,xnเป็นมาตรฐานหากค่าเฉลี่ยของทุกค่าคือ 0 และส่วนเบี่ยงเบนมาตรฐานคือ 1 วิธีหนึ่งในการคำนวณนี่คือวิธีแรกคือการคำนวณค่าเฉลี่ยμและส่วนเบี่ยงเบนมาตรฐานσเป็น
    μ=1ni=1nxiσ=1ni=1n(xiμ)2,
    และจากนั้นคอมพิวเตอร์มาตรฐานโดยการเปลี่ยนทุกxiกับxiμσσ
  • คุณสามารถสรุปได้ว่าการป้อนข้อมูลที่มีอย่างน้อยสองรายการที่แตกต่างกัน (ซึ่งหมายถึงσ0 )
  • โปรดทราบว่าการใช้งานบางคนใช้ค่าเบี่ยงเบนมาตรฐานของกลุ่มตัวอย่างซึ่งไม่เท่ากับค่าเบี่ยงเบนมาตรฐานของประชากรσเราจะใช้ที่นี่
  • มีเป็นคำตอบ CWสำหรับทุกการแก้ปัญหาจิ๊บจ๊อย

ตัวอย่าง

[1,2,3] -> [-1.224744871391589,0.0,1.224744871391589]
[1,2] -> [-1,1]
[-3,1,4,1,5] -> [-1.6428571428571428,-0.21428571428571433,0.8571428571428572,-0.21428571428571433,1.2142857142857144]

(ตัวอย่างเหล่านี้สร้างด้วยสคริปต์นี้)

คำตอบ:




5

APL (Dyalog Classic) , 21 20 19 ไบต์

(-÷.5*⍨⊢÷⌹×≢)+/-⊢×≢

ลองออนไลน์!

⊢÷⌹ คือผลรวมของกำลังสอง

⊢÷⌹×≢ คือผลรวมของกำลังสองหารด้วยความยาว


ว้าว. ฉันไม่ควรแปลกใจอีกต่อไป แต่ฉันทุกครั้ง
Quintec


4

APL + WIN, 41,32 30 ไบต์

บันทึกไปแล้ว 9 ไบต์ขอบคุณ Erik + อีก 2 ขอบคุณ ngn

x←v-(+/v)÷⍴v←⎕⋄x÷(+/x×x÷⍴v)*.5

พรอมต์สำหรับเวกเตอร์ของตัวเลขและคำนวณค่าเฉลี่ยเบี่ยงเบนมาตรฐานและองค์ประกอบมาตรฐานของเวกเตอร์อินพุต


คุณไม่สามารถกำหนดx←v-(+/v)÷⍴v←⎕และทำx÷((+/x*2)÷⍴v)*.5อะไรได้บ้าง
Erik the Outgolfer

ฉันทำได้แน่นอน ขอบคุณ
เกรแฮม

apl + win ทำส่วนขยายเดี่ยว ( 1 2 3+,4←→ 1 2 3+4) หรือไม่ ถ้าใช่คุณสามารถเขียนใหม่(+/x*2)÷⍴vเป็น+/x×x÷⍴v
ngn

@ngn ใช้งานได้อีก 2 ไบต์ ขอบคุณ
เกรแฮม

3

R + pryr, 53 52 ไบต์

-1 ไบต์ใช้sum(x|1)แทนlength(x)เห็นได้ในโซลูชันของ @Robert S.

pryr::f((x-(y<-mean(x)))/(sum((x-y)^2)/sum(x|1))^.5)

สำหรับการเป็นภาษาที่สร้างขึ้นสำหรับนักสถิติฉันประหลาดใจที่นี่ไม่มีฟังก์ชั่นในตัว อย่างน้อยฉันก็หาไม่เจอ แม้แต่ฟังก์ชั่นmosaic::zscoreก็ไม่ได้ผลลัพธ์ตามที่คาดหวัง สิ่งนี้น่าจะเกิดจากการใช้ค่าเบี่ยงเบนมาตรฐานประชากรแทนค่าเบี่ยงเบนมาตรฐานตัวอย่าง

ลองออนไลน์!


2
คุณสามารถเปลี่ยน<-เป็น a =เพื่อบันทึก 1 ไบต์
Robert S.

@ J.Doe ไม่ฉันใช้วิธีที่ฉันแสดงความคิดเห็นในการแก้ปัญหาของ Robert S. scaleเรียบร้อย!
Giuseppe

2
@ J.Doe เนื่องจากคุณจะใช้nเมื่อคุณสามารถใช้งานได้โดยตรง38 ไบต์
Giuseppe

2
@RobertS PPCG ที่นี่เรามีแนวโน้มที่จะสนับสนุนให้มีความยืดหยุ่นในการป้อนข้อมูลและการส่งออกรวมถึงการส่งออกมากกว่าที่จำเป็นยกเว้นความท้าทายที่รูปแบบที่แม่นยำของการส่งออกเป็นจุดรวมของความท้าทาย
ngm

6
แน่นอนว่าบิวด์อิน R จะไม่ใช้ "ความแปรปรวนประชากร" มีเพียงวิศวกรที่สับสนเท่านั้นที่จะใช้สิ่งนี้ (ดังนั้น Python และคำตอบ Matlab;))
ngm


2

เยลลี่ 10 ไบต์

_ÆmµL½÷ÆḊ×

ลองออนไลน์!

มันไม่ได้สั้นกว่านี้ แต่ฟังก์ชันดีเทอร์มิแนนต์ของ Jelly ÆḊยังคำนวณค่าปกติของเวคเตอร์

_Æm             x - mean(x)
   µ            then:
    L½          Square root of the Length
      ÷ÆḊ       divided by the norm
         ×      Multiply by that value

Hey, nice alternative! Unfortunately, I can't see a way to shorten it.
Erik the Outgolfer

2

Mathematica, 25 bytes

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

Pure function. Takes a list of numbers as input and returns a list of machine-precision numbers as output. Note that the built-in Standardize function uses the sample variance by default.


2

J, 22 bytes

-1 byte thanks to Cows quack!

(-%[:%:1#.-*-%#@[)+/%#

Try it online!

J, 31 23 bytes

(-%[:%:#@[%~1#.-*-)+/%#

Try it online!

                   +/%# - mean (sum (+/) divided (%) by the number of samples (#)) 
(                 )     - the list is a left argument here (we have a hook)
                 -      - the difference between each sample and the mean
                *       - multiplied by 
               -        - the difference between each sample and the mean
            1#.         - sum by base-1 conversion
          %~            - divided by
       #@[              - the length of the samples list
     %:                 - square root
   [:                   - convert to a fork (function composition) 
 -                      - subtract the mean from each sample
  %                     - and divide it by sigma

1
Rearranging it gives 22 [:(%[:%:1#.*:%#)]-+/%# tio.run/##y/qfVmyrp2CgYKVg8D/…, I think one of those caps could be removed, but haven't had any luck so far, EDIT: a more direct byteshaving is (-%[:%:1#.-*-%#@[)+/%# also at 22
user41805

@Cows quack Thanks!
Galen Ivanov


2

Haskell, 80 75 68 bytes

t x=k(/sqrt(f$sum$k(^2)))where k g=g.(-f(sum x)+)<$>x;f=(/sum(1<$x))

Thanks to @flawr for the suggestions to use sum(1<$x) instead of sum[1|_<-x] and to inline the mean, @xnor for inlining the standard deviation and other reductions.

Expanded:

-- Standardize a list of values of any floating-point type.
standardize :: Floating a => [a] -> [a]
standardize input = eachLessMean (/ sqrt (overLength (sum (eachLessMean (^2)))))
  where

    -- Map a function over each element of the input, less the mean.
    eachLessMean f = map (f . subtract (overLength (sum input))) input

    -- Divide a value by the length of the input.
    overLength n = n / sum (map (const 1) input)

1
You can replace [1|_<-x] with (1<$x) to save a few bytes. That is a great trick for avoiding the fromIntegral, that I haven't seen so far!
flawr

By the way: I like using tryitonline, you can run your code there and then copy the preformatted aswer for posting here!
flawr


You can write (-x+) for (+(-x)) to avoid parens. Also it looks like f can be pointfree: f=(/sum(1<$x)), and s can be replaced with its definition.
xnor

@xnor Ooh, (-x+) is handy, I’m sure I’ll be using that in the future
Jon Purdy

2

MathGolf, 7 bytes

▓-_²▓√/

Try it online!

Explanation

This is literally a byte-for-byte recreation of Kevin Cruijssen's 05AB1E answer, but I save some bytes from MathGolf having 1-byters for everything needed for this challenge. Also the answer looks quite good in my opinion!

▓         get average of list
 -        pop a, b : push(a-b)
  _       duplicate TOS
   ²      pop a : push(a*a)
    ▓     get average of list
     √    pop a : push(sqrt(a)), split string to list
      /   pop a, b : push(a/b), split strings

1

JavaScript (ES7),  80  79 bytes

a=>a.map(x=>(x-g(a))/g(a.map(x=>(x-m)**2))**.5,g=a=>m=eval(a.join`+`)/a.length)

Try it online!

Commented

a =>                      // given the input array a[]
  a.map(x =>              // for each value x in a[]:
    (x - g(a)) /          //   compute (x - mean(a)) divided by
    g(                    //   the standard deviation:
      a.map(x =>          //     for each value x in a[]:
        (x - m) ** 2      //       compute (x - mean(a))²
      )                   //     compute the mean of this array
    ) ** .5,              //   and take the square root
    g = a =>              //   g = helper function taking an array a[],
      m = eval(a.join`+`) //     computing the mean
          / a.length      //     and storing the result in m
  )                       // end of outer map()


1

Haskell, 59 bytes

(%)i=sum.map(^i)
f l=[(0%l*y-1%l)/sqrt(2%l*0%l-1%l^2)|y<-l]

Try it online!

Doesn't use libraries.

The helper function % computes the sum of ith powers of a list, which lets us get three useful values.

  • 0%l is the length of l (call this n)
  • 1%l is the sum of l (call this s)
  • 2%l is the sum of squares of l (call this m)

We can express the z-score of an element y as

(n*y-s)/sqrt(n*v-s^2)

(This is the expression (y-s/n)/sqrt(v/n-(s/n)^2) simplified a bit by multiplying the top and bottom by n.)

We can insert the expressions 0%l, 1%l, 2%l without parens because the % we define has higher precedence than the arithmetic operators.

(%)i=sum.map(^i) is the same length as i%l=sum.map(^i)l. Making it more point-free doesn't help. Defining it like g i=... loses bytes when we call it. Although % works for any list but we only call it with the problem input list, there's no byte loss in calling it with argument l every time because a two-argument call i%l is no longer than a one-argument one g i.


We do have LATEX here:)
flawr

I really like the % idea! It looks just like the discrete version of the statistical moments.
flawr

1

K (oK), 33 23 bytes

-10 bytes thanks to ngn!

{t%%(+/t*t:x-/x%#x)%#x}

Try it online!

First attempt at coding (I don't dare to name it "golfing") in K. I'm pretty sure it can be done much better (too many variable names here...)


1
nice! you can replace the initial (x-m) with t (tio)
ngn

1
the inner { } is unnecessary - its implicit parameter name is x and it has been passed an x as argument (tio)
ngn

1
another -1 byte by replacing x-+/x with x-/x. the left argument to -/ serves as initial value for the reduction (tio)
ngn

@ngn Thank you! Now I see that the first 2 golfs are obvious; the last one is beyond my current level :)
Galen Ivanov


1

TI-Basic (83 series), 14 11 bytes

Ans-mean(Ans
Ans/√(mean(Ans²

Takes input in Ans. For example, if you type the above into prgmSTANDARD, then {1,2,3}:prgmSTANDARD will return {-1.224744871,0.0,1.224744871}.

Previously, I tried using the 1-Var Stats command, which stores the population standard deviation in σx, but it's less trouble to compute it manually.


1

05AB1E, 9 bytes

ÅA-DnÅAt/

Port of @Arnauld's JavaScript answer, so make sure to upvote him!

Try it online or verify all test cases.

Explanation:

ÅA          # Calculate the mean of the (implicit) input
            #  i.e. [-3,1,4,1,5] → 1.6
  -         # Subtract it from each value in the (implicit) input
            #  i.e. [-3,1,4,1,5] and 1.6 → [-4.6,-0.6,2.4,-0.6,3.4]
   D        # Duplicate that list
    n       # Take the square of each
            #  i.e. [-4.6,-0.6,2.4,-0.6,3.4] → [21.16,0.36,5.76,0.36,11.56]
     ÅA     # Pop and calculate the mean of that list
            #  i.e. [21.16,0.36,5.76,0.36,11.56] → 7.84
       t    # Take the square-root of that
            #  i.e. 7.84 → 2.8
        /   # And divide each value in the duplicated list with it (and output implicitly)
            #  i.e. [-4.6,-0.6,2.4,-0.6,3.4] and 2.8 → [-1.6428571428571428,
            #   -0.21428571428571433,0.8571428571428572,-0.21428571428571433,1.2142857142857144]


0

Pyth, 21 19 bytes

mc-dJ.OQ@.Om^-Jk2Q2

Try it online here.

mc-dJ.OQ@.Om^-Jk2Q2Q   Implicit: Q=eval(input())
                       Trailing Q inferred
    J.OQ               Take the average of Q, store the result in J
           m     Q     Map the elements of Q, as k, using:
             -Jk         Difference between J and k
            ^   2        Square it
         .O            Find the average of the result of the map
        @         2    Square root it
                       - this is the standard deviation of Q
m                  Q   Map elements of Q, as d, using:
  -dJ                    d - J
 c                       Float division by the standard deviation
                       Implicit print result of map

Edit: after seeing Kevin's answer, changed to use the average builtin for the inner results. Previous answer: mc-dJ.OQ@csm^-Jk2QlQ2


0

SNOBOL4 (CSNOBOL4), 229 bytes

	DEFINE('Z(A)')
Z	X =X + 1
	M =M + A<X>	:S(Z)
	N =X - 1.
	M =M / N
D	X =GT(X) X - 1	:F(S)
	A<X> =A<X> - M	:(D)
S	X =LT(X,N) X + 1	:F(Y)
	S =S + A<X> ^ 2 / N	:(S)
Y	S =S ^ 0.5
N	A<X> =A<X> / S
	X =GT(X) X - 1	:S(N)
	Z =A	:(RETURN)

Try it online!

Link is to a functional version of the code which constructs an array from STDIN given its length and then its elements, then runs the function Z on that, and finally prints out the values.

Defines a function Z which returns an array.

The 1. on line 4 is necessary to do the floating point arithmetic properly.



0

Charcoal, 25 19 bytes

≧⁻∕ΣθLθθI∕θ₂∕ΣXθ²Lθ

Try it online! Link is to verbose version of code. Explanation:

       θ    Input array
≧           Update each element
 ⁻          Subtract
   Σ        Sum of
    θ       Input array
  ∕         Divided by
     L      Length of
      θ     Input array

Calculate μ and vectorised subtract it from each xi.

  θ         Updated array
 ∕          Vectorised divided by
   ₂        Square root of
     Σ      Sum of
       θ    Updated array
      X     Vectorised to power
        ²   Literal 2
    ∕       Divided by
         L  Length of
          θ Array
I           Cast to string
            Implicitly print each element on its own line.

Calculate σ, vectorised divide each xi by it, and output the result.

Edit: Saved 6 bytes thanks to @ASCII-only for a) using SquareRoot() instead of Power(0.5) b) fixing vectorised Divide() (it was doing IntDivide() instead) c) making Power() vectorise.


crossed out 25 = no bytes? :P (Also, you haven't updated the TIO link yet)
ASCII-only

@ASCII-only Oops, thanks!
Neil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.