Standardiser les échantillons (calculer le z-score)

14

Étant donné une liste de nombres à virgule flottante, standardisez-la .

Détails

  • Une liste x1,x2,,xn est normalisée si la moyenne de toutes les valeurs est 0, et l' écart-type est 1. Une façon de calculer cela est en calculant d'abord la moyenne μ et l'écart-type σ comme
    μ=1ni=1nxiσ=1ni=1n(xiμ)2,
    puis calcul de la normalisation en remplaçant chaquexiparxiμσ .
  • Vous pouvez supposer que l'entrée contient au moins deux entrées distinctes (ce qui implique σ0 ).
  • Notez que certaines implémentations utilisent l'écart type d'échantillon, qui n'est pas égal à l'écart type de population σ nous utilisons ici.
  • Il existe une réponse CW pour toutes les solutions triviales .

Exemples

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

(Ces exemples ont été générés avec ce script .)

flawr
la source

Réponses:

7

R , 51 45 38 37 octets

Merci à Giuseppe et J.Doe!

function(x)scale(x)/(1-1/sum(x|1))^.5

Essayez-le en ligne!

Robert S.
la source
Battez-moi de 2 octets et 1 minute
Sumner18
5

APL (Dyalog Classic) , 21 20 19 octets

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

Essayez-le en ligne!

⊢÷⌹ est la somme des carrés

⊢÷⌹×≢ est la somme des carrés divisée par la longueur

ngn
la source
Sensationnel. Je ne devrais plus être surpris, mais je le suis à chaque fois
Quintec
4

MATL , 10 octets

tYm-t&1Zs/

Essayez-le en ligne!

Explication

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

APL + WIN, 41,32 30 octets

9 octets économisés grâce à Erik + 2 de plus grâce à ngn

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

Demande le vecteur de nombres et calcule l'écart type moyen et les éléments normalisés du vecteur d'entrée

Graham
la source
Tu ne peux pas assigner x←v-(+/v)÷⍴v←⎕et ensuite faire x÷((+/x*2)÷⍴v)*.5?
Erik the Outgolfer
Je peux en effet. Merci.
Graham
apl + win fait-il l'extension singleton ( 1 2 3+,4← → 1 2 3+4)? si oui, vous pouvez réécrire (+/x*2)÷⍴vcomme+/x×x÷⍴v
ngn
@ngn Cela fonctionne pour 2 autres octets. Merci.
Graham
3

R + pryr, 53 52 octets

-1 octet utilisant sum(x|1)au lieu de length(x)comme vu dans la solution de @Robert S.

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

Pour être un langage construit pour les statisticiens, je suis étonné que cela n'ait pas de fonction intégrée. Du moins pas une que j'ai pu trouver. Même la fonction mosaic::zscorene donne pas les résultats escomptés. Cela est probablement dû à l'utilisation de l'écart type de la population au lieu de l'écart type de l'échantillon.

Essayez-le en ligne!

Sumner18
la source
2
Vous pouvez changer le <-en a =pour économiser 1 octet.
Robert S.
@ J.Doe non, j'ai utilisé la méthode que j'ai commentée sur la solution de Robert S. scaleest bien!
Giuseppe
2
@ J.Doe puisque vous n'utilisez nqu'une seule fois que vous pouvez l'utiliser directement pendant 38 octets
Giuseppe
2
@RobertS. ici sur PPCG, nous avons tendance à encourager une entrée et une sortie flexibles, y compris une sortie supérieure à ce qui est nécessaire, à l'exception des défis où la disposition précise de la sortie est le point essentiel du défi.
ngm
6
Bien sûr, les fonctions intégrées R n'utilisaient pas la "variance de la population". Seuls les ingénieurs confus utiliseraient une telle chose (hencethe réponses Python et Matlab;))
ngm
3

Tcl , 126 octets

proc S L {lmap c $L {expr ($c-[set m ([join $L +])/[set n [llength $L]].])/sqrt(([join [lmap c $L {expr ($c-$m)**2}] +])/$n)}}

Essayez-le en ligne!

sergiol
la source
2

Gelée , 10 octets

_ÆmµL½÷ÆḊ×

Essayez-le en ligne!

Ce n'est pas plus court, mais la fonction déterminante de Jelly ÆḊcalcule également la norme vectorielle.

_Æm             x - mean(x)
   µ            then:
    L½          Square root of the Length
      ÷ÆḊ       divided by the norm
         ×      Multiply by that value
lirtosiast
la source
Hé, belle alternative! Malheureusement, je ne vois pas de moyen de le raccourcir.
Erik the Outgolfer
2

Mathematica, 25 octets

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

Fonction pure. Prend une liste de nombres en entrée et renvoie une liste de nombres de précision machine en sortie. Notez que la Standardizefonction intégrée utilise la variance d'échantillon par défaut.

LegionMammal978
la source
2

J , 22 octets

-1 octet grâce au charlatan des vaches!

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

Essayez-le en ligne!

J , 31 23 octets

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

Essayez-le en ligne!

                   +/%# - 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
Galen Ivanov
la source
1
Le réorganiser donne 22 [:(%[:%:1#.*:%#)]-+/%# tio.run/##y/qfVmyrp2CgYKVg8D/… , je pense que l'un de ces plafonds pourrait être supprimé, mais n'a pas eu de chance jusqu'à présent, EDIT: un byteshaving plus direct est (-%[:%:1#.-*-%#@[)+/%#également au 22
Kritixi Lithos
@Cows quack Merci!
Galen Ivanov,
2

APL (Dyalog Unicode) , 33 29 octets

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

-4 octets grâce à @ngn

Essayez-le en ligne!

Quintec
la source
vous pouvez attribuer ⍵-mà une variable et supprimer m←comme ceci:{d÷.5*⍨l÷⍨+/×⍨d←⍵-(+/⍵)÷l←≢⍵}
ngn
@ngn Ah, bien, merci, je n'ai pas vu cette duplication d'une manière ou d'une autre
Quintec
2

Haskell, 80 75 68 octets

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

Merci à @flawr pour les suggestions à utiliser sum(1<$x)au lieu de sum[1|_<-x]et pour aligner la moyenne, @xnor pour avoir inclus l'écart type et d'autres réductions.

Étendu:

-- 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)
Jon Purdy
la source
1
Vous pouvez remplacer [1|_<-x]par (1<$x)pour économiser quelques octets. C'est une excellente astuce pour éviter le fromIntegral, que je n'ai pas vu jusqu'à présent!
flawr
Soit dit en passant: j'aime utiliser tryitonline , vous pouvez y exécuter votre code, puis copier la réponse préformatée pour publication ici!
flawr
Et vous n'avez pas à définir m .
flawr
Vous pouvez écrire (-x+)pour (+(-x))éviter les parens. Il fpeut également sembler être sans point: f=(/sum(1<$x))et speut être remplacé par sa définition.
2018
@xnor Ooh, (-x+)c'est pratique, je suis sûr que je vais l'utiliser à l'avenir
Jon Purdy
2

MathGolf , 7 octets

▓-_²▓√/

Essayez-le en ligne!

Explication

Il s'agit littéralement d'une recréation octet par octet de la réponse 05AB1E de Kevin Cruijssen, mais j'économise quelques octets de MathGolf ayant 1 octet pour tout ce qui est nécessaire pour ce défi. De plus, la réponse semble assez bonne à mon avis!

▓         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
maxb
la source
1

JavaScript (ES7),  80  79 octets

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

Essayez-le en ligne!

Commenté

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()
Arnauld
la source
1

Haskell , 59 octets

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

Essayez-le en ligne!

N'utilise pas de bibliothèques.

La fonction d'assistance %calcule la somme des ipuissances d'une liste, ce qui nous permet d'obtenir trois valeurs utiles.

  • 0%lest la longueur de l(appelez cela n)
  • 1%lest la somme de l(appelez celas )
  • 2%lest la somme des carrés de l(appelez cela m)

Nous pouvons exprimer le z-score d'un élément ycomme

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

(C'est l'expression (y-s/n)/sqrt(v/n-(s/n)^2)simplifiée un peu en multipliant le haut et le bas par n.)

Nous pouvons insérer les expressions 0%l, 1%l, 2%lsans parens parce que %nous définissons a une priorité plus élevée que les opérateurs arithmétiques.

(%)i=sum.map(^i)est de la même longueur que i%l=sum.map(^i)l. Le rendre plus sans points n'aide pas. Le définir comme g i=...perd des octets lorsque nous l'appelons. Bien que cela %fonctionne pour n'importe quelle liste mais que nous l'appelons uniquement avec la liste d'entrée de problème, il n'y a pas de perte d'octet en l'appelant à lchaque fois avec un argument car un appel à deux arguments i%ln'est pas plus long qu'un appel à un argument g i.

xnor
la source
On possède LUNETEXici :)
flawr
J'aime vraiment l' %idée! Cela ressemble à la version discrète des moments statistiques .
flawr
1

K (oK) , 33 23 octets

-10 octets grâce à ngn!

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

Essayez-le en ligne!

Première tentative de codage (je n'ose pas le nommer "golf") en K. Je suis sûr que cela peut être fait beaucoup mieux (trop de noms de variables ici ...)

Galen Ivanov
la source
1
agréable! vous pouvez remplacer l'initiale (x-m)par t( tio )
ngn
1
l'intérieur { }n'est pas nécessaire - son nom de paramètre implicite est xet il a été passé un xargument as ( tio )
ngn
1
un autre -1 octet en remplaçant x-+/xpar x-/x. l'argument gauche -/sert de valeur initiale pour la réduction ( tio )
ngn
@ngn Merci! Maintenant, je vois que les 2 premiers golfs sont évidents; le dernier est au-delà de mon niveau actuel :)
Galen Ivanov
1

MATLAB, 26 octets

Trivial-ish, std(,1)pour utiliser l'écart-type de la population

f=@(x)(x-mean(x))/std(x,1)
aaaaa dit réintégrer Monica
la source
1

TI-Basic (série 83), 14 11 octets

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

Prend entrée Ans. Par exemple, si vous saisissez ce qui précède prgmSTANDARD, alors {1,2,3}:prgmSTANDARDreviendra {-1.224744871,0.0,1.224744871}.

Auparavant, j'essayais d'utiliser la 1-Var Statscommande, qui stocke l'écart-type de la population σx, mais il est moins difficile de le calculer manuellement.

Misha Lavrov
la source
1

05AB1E , 9 octets

ÅA-DnÅAt/

Port de la réponse JavaScript de @Arnauld , alors assurez-vous de voter pour lui!

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

Å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]
Kevin Cruijssen
la source
0

Pyth, 21 19 octets

[email protected]^-Jk2Q2

Essayez-le en ligne ici .

[email protected]^-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: après avoir vu la réponse de Kevin , a changé pour utiliser la moyenne intégrée pour les résultats internes. Réponse précédente:mc-dJ.OQ@csm^-Jk2QlQ2

Sok
la source
0

SNOBOL4 (CSNOBOL4) , 229 octets

	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)

Essayez-le en ligne!

Le lien est vers une version fonctionnelle du code qui construit un tableau à partir de STDIN compte tenu de sa longueur puis de ses éléments, puis exécute la fonction Z sur cela et finalement affiche les valeurs.

Définit une fonction Z qui renvoie un tableau.

La 1.ligne 4 est nécessaire pour effectuer correctement l'arithmétique en virgule flottante.

Giuseppe
la source
0

Fusain , 25 19 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

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

Calculer μ et vectorisé le soustraire de chaque Xje.

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

Calculer σ, vectorisé diviser chacun Xje par elle, et sortir le résultat.

Edit: 6 octets enregistrés grâce à @ ASCII uniquement pour a) utiliser SquareRoot()au lieu de Power(0.5)b) fixer vectorisé Divide()(il le faisait à la IntDivide()place) c) faire Power()vectoriser.

Neil
la source
barré 25 = pas d'octets? : P (De plus, vous n'avez pas encore mis à jour le lien TIO)
ASCII uniquement
@ Oups ASCII uniquement, merci!
Neil