Estandarizar las muestras (Calcular la puntuación z)


14

Dada una lista de números de coma flotante, estandarícela .

Detalles

  • Una lista x1,x2,,xn está estandarizada si la media de todos los valores es 0, y la desviación estándar es 1. Una forma de calcular esto es calculando primero la media μ y la desviación estándar σ como
    μ=1ni=1nxiσ=1ni=1n(xiμ)2,
    y luego calcular la estandarización reemplazando cadaxiconxiμσ .
  • Puede suponer que la entrada contiene al menos dos entradas distintas (lo que implica σ0 ).
  • Tenga en cuenta que algunas implementaciones usan la desviación estándar de muestra, que no es igual a la desviación estándar de la población σ que estamos usando aquí.
  • Hay una respuesta CW para todas las soluciones triviales .

Ejemplos

[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]

(Estos ejemplos se han generado con este script ).

Respuestas:





4

MATL , 10 bytes

tYm-t&1Zs/

Pruébalo en línea!

Explicación

t       % Implicit input
        % Duplicate
Ym      % Mean
-       % Subtract, element-wise
t       % Duplicate
&1Zs    % Standard deviation using normalization by n
/       % Divide, element-wise
        % Implicit display

4

APL + WIN, 41,32 30 bytes

9 bytes guardados gracias a Erik + 2 más gracias a ngn

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

Solicita el vector de números y calcula la desviación estándar media y los elementos estandarizados del vector de entrada


¿No puedes asignar x←v-(+/v)÷⍴v←⎕y luego hacer x÷((+/x*2)÷⍴v)*.5?
Erik the Outgolfer

De hecho puedo. Gracias.
Graham

¿apl + win hace extensión singleton ( 1 2 3+,4← → 1 2 3+4)? en caso afirmativo, puede volver a escribir (+/x*2)÷⍴vcomo+/x×x÷⍴v
ngn

@ngn Eso funciona para otros 2 bytes. Gracias.
Graham

3

R + pryr, 53 52 bytes

-1 byte usando en sum(x|1)lugar de length(x)como se ve en la solución de @Robert S.

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

Por ser un lenguaje creado para estadísticos, me sorprende que esto no tenga una función incorporada. Al menos no uno que pude encontrar. Incluso la función mosaic::zscoreno produce los resultados esperados. Esto probablemente se deba al uso de la desviación estándar de la población en lugar de la desviación estándar de la muestra.

Pruébalo en línea!


2
Puede cambiar el <-a a =para guardar 1 byte.
Robert S.

@ J.Doe no, utilicé el método que comenté sobre la solución de Robert S. scaleestá ordenado!
Giuseppe

2
@ J.Doe ya que solo lo usa nuna vez que puede usarlo directamente por 38 bytes
Giuseppe

2
@RobertS. aquí en PPCG tendemos a alentar la posibilidad de permitir entradas y salidas flexibles, incluida la salida de más de lo requerido, con la excepción de los desafíos donde el diseño preciso de la salida es el punto central del desafío.
ngm

66
Por supuesto, los R incorporados no usarían "variación de población". Solo los ingenieros confundidos usarían tal cosa (de ahí las respuestas de Python y Matlab;))
ngm


2

Jalea , 10 bytes

_ÆmµL½÷ÆḊ×

Pruébalo en línea!

No es más corto, pero la función determinante de Jelly ÆḊtambién calcula la norma vectorial.

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

¡Hola, buena alternativa! Desafortunadamente, no puedo ver una forma de acortarlo.
Erik the Outgolfer

2

Mathematica, 25 bytes

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

Pura función. Toma una lista de números como entrada y devuelve una lista de números de precisión de máquina como salida. Tenga en cuenta que la Standardizefunción integrada utiliza la varianza de muestra de forma predeterminada.


2

J , 22 bytes

-1 byte gracias a Cows quack!

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

Pruébalo en línea!

J , 31 23 bytes

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

Pruébalo en línea!

                   +/%# - 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
Reorganizarlo da 22 [:(%[:%:1#.*:%#)]-+/%# tio.run/##y/qfVmyrp2CgYKVg8D/… , creo que uno de esos límites podría eliminarse, pero hasta ahora no he tenido suerte, EDITAR: un bytes de almacenamiento más directo (-%[:%:1#.-*-%#@[)+/%#también está en 22
Kritixi Lithos

@Cows quack ¡Gracias!
Galen Ivanov

2

APL (Dyalog Unicode) , 33 29 bytes

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

-4 bytes gracias a @ngn

Pruébalo en línea!


podría asignar ⍵-ma una variable y eliminar de m←esta manera:{d÷.5*⍨l÷⍨+/×⍨d←⍵-(+/⍵)÷l←≢⍵}
ngn

@ngn Ah, bien, gracias, no vi esa duplicación de alguna manera
Quintec

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))

Gracias a @flawr por las sugerencias para usar en sum(1<$x)lugar de sum[1|_<-x]e incluir la media, @xnor por incluir la desviación estándar y otras reducciones.

Expandido:

-- 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
Puede reemplazar [1|_<-x]con (1<$x)para guardar algunos bytes. ¡Es un gran truco para evitar el fromIntegralque no he visto hasta ahora!
falla

Por cierto: ¡me gusta usar tryitonline , puede ejecutar su código allí y luego copiar la respuesta preformateada para publicar aquí!
flawr


Puede escribir (-x+)para (+(-x))evitar padres. También parece que fpuede ser pointfree:, f=(/sum(1<$x))y sse puede reemplazar con su definición.
xnor

@xnor Ooh, (-x+)es útil, estoy seguro de que lo usaré en el futuro
Jon Purdy

2

MathGolf , 7 bytes

▓-_²▓√/

Pruébalo en línea!

Explicación

Esto es literalmente una recreación byte por byte de la respuesta 05AB1E de Kevin Cruijssen, pero guardo algunos bytes de MathGolf con 1 byters para todo lo necesario para este desafío. ¡También la respuesta se ve bastante bien en mi opinión!

▓         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)

Pruébalo en línea!

Comentado

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]

Pruébalo en línea!

No usa bibliotecas.

La función auxiliar %calcula la suma de las ipotencias de una lista, lo que nos permite obtener tres valores útiles.

  • 0%les la longitud de l(llame a esto n)
  • 1%les la suma de l(llame a esto s)
  • 2%les la suma de cuadrados de l(llame a esto m)

Podemos expresar la puntuación z de un elemento ycomo

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

(Esta es la expresión (y-s/n)/sqrt(v/n-(s/n)^2)simplificada un poco al multiplicar la parte superior e inferior por n).

Podemos insertar las expresiones 0%l, 1%l, 2%lsin parens debido a que la %definimos tiene mayor precedencia que los operadores aritméticos.

(%)i=sum.map(^i)tiene la misma longitud que i%l=sum.map(^i)l. Hacerlo más libre de puntos no ayuda. Definirlo como g i=...pierde bytes cuando lo llamamos. Aunque %funciona para cualquier lista, pero solo la llamamos con la lista de entrada del problema, no hay pérdida de bytes al llamarla con argumento lcada vez porque una llamada de dos argumentos i%lno es más larga que una de un argumento g i.


Nosotros tenemos LUNTmiXaquí :)
flawr

¡Realmente me gusta la %idea! Se parece a la versión discreta de los momentos estadísticos .
falla

1

K (oK) , 33 23 bytes

-10 bytes gracias a ngn!

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

Pruébalo en línea!

Primer intento de codificación (no me atrevo a llamarlo "golf") en K. Estoy bastante seguro de que se puede hacer mucho mejor (demasiados nombres de variables aquí ...)


1
¡bonito! puede reemplazar la inicial (x-m)con t( tio )
ngn

1
lo interno { }es innecesario - su nombre de parámetro implícito es xy se le pasó xcomo argumento ( tio )
ngn

1
otro -1 byte reemplazando x-+/xcon x-/x. el argumento izquierdo -/sirve como valor inicial para la reducción ( tio )
ngn

@ngn ¡Gracias! Ahora veo que los primeros 2 campos de golf son obvios; el último está más allá de mi nivel actual :)
Galen Ivanov


1

TI-Basic (serie 83), 14 11 bytes

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

Toma entrada Ans. Por ejemplo, si escribe lo anterior en prgmSTANDARD, entonces {1,2,3}:prgmSTANDARDvolverá {-1.224744871,0.0,1.224744871}.

Anteriormente, intenté usar el 1-Var Statscomando, que almacena la desviación estándar de la población σx, pero es menos problemático calcularlo manualmente.


1

05AB1E , 9 bytes

ÅA-DnÅAt/

Puerto de la respuesta de JavaScript de @Arnauld , ¡así que asegúrese de votarlo!

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

Å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

Pruébelo en línea aquí .

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

Editar: después de ver la respuesta de Kevin , cambió para usar el promedio incorporado para los resultados internos. Respuesta anterior: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)

Pruébalo en línea!

Link es a una versión funcional del código que construye una matriz a partir de STDIN dada su longitud y luego sus elementos, luego ejecuta la función Zsobre eso y finalmente imprime los valores.

Define una función Zque devuelve una matriz.

La 1.línea 4 es necesaria para hacer la aritmética de coma flotante correctamente.



0

Carbón , 25 19 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

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

Calcular μ y vectorizado restarlo de cada Xyo.

  θ         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.

Calcular σ, vectorizados dividir cada uno Xyo por él, y generar el resultado.

Editar: guardado 6 bytes gracias a @ ASCII-only para a) usar en SquareRoot()lugar de Power(0.5)b) arreglar vectorized Divide()(en su IntDivide()lugar) c) hacer Power()vectorise.


tachado 25 = sin bytes? : P (Además, todavía no has actualizado el enlace TIO)
Solo para ASCII el

@ Solo ASCII ¡Vaya, gracias!
Neil
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.