Стандартизировать образцы (вычислить 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]

(Эти примеры были созданы с помощью этого сценария .)

Ответы:






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?
Эрик Outgolfer

Я действительно могу. Благодарю.
Грэм

apl + win делает одноэлементное расширение ( 1 2 3+,4← → 1 2 3+4)? если да, вы можете переписать (+/x*2)÷⍴vкак+/x×x÷⍴v
нгн

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

For being a language built for statisticians, I'm amazed that this doesn't have a built-in function. At least not one that I could find. Even the function mosaic::zscore doesn't yield the expected results. This is likely due to using the population standard deviation instead of sample standard deviation.

Try it online!


2
You can change the <- into a = to save 1 byte.
Robert S.

@J.Doe nope, I used the method I commented on Robert S.'s solution. scale is neat!
Giuseppe

2
@J.Doe since you only use n once you can use it directly for 38 bytes
Giuseppe

2
@RobertS. here on PPCG we tend to encourage allowing flexible input and output, including outputting more than is required, with the exception of challenges where the precise layout of the output is the whole point of the challenge.
ngm

6
Of course R built-ins wouldn't use "population variance". Only confused engineers would use such a thing (hencethe Python and Matlab answers ;))
ngm


2

Jelly, 10 bytes

_ÆmµL½÷ÆḊ×

Try it online!

It's not any shorter, but Jelly's determinant function ÆḊ also calculates vector norm.

_Æ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
Kritixi Lithos

@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


Вы можете написать (-x+)для , (+(-x))чтобы избежать круглых скобок. Также похоже, что fможет быть pointfree: f=(/sum(1<$x))и sможет быть заменено его определением.
xnor

@xnor Ох, (-x+)удобно, я уверен, что буду использовать это в будущем
Джон Перди

2

MathGolf, 7 bytes

▓-_²▓√/

Try it online!

Explanation

Это буквально побайтовое воссоздание ответа 05AB1E Кевина Круйссена, но я спасаю некоторые байты из MathGolf, имеющие 1 байт для всего, что нужно для этого испытания. Кроме того, ответ выглядит довольно хорошо, на мой взгляд!

▓         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 байт

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

Попробуйте онлайн!

комментарии

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 байт

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

Попробуйте онлайн!

Не использует библиотеки.

Вспомогательная функция %вычисляет сумму iстепеней списка, что позволяет нам получить три полезных значения.

  • 0%lэто длина l(назовите это n)
  • 1%lэто сумма l(назовите этоs )
  • 2%lэто сумма квадратов l(назовите это m)

Мы можем выразить z-счет элемента yкак

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

(Это выражение (y-s/n)/sqrt(v/n-(s/n)^2)немного упростили, умножив верхнюю и нижнюю на n.)

Мы можем вставить выражения 0%l, 1%l, 2%lбез скобок , так как %мы определяем , имеет более высокий приоритет , чем арифметические операторы.

(%)i=sum.map(^i)такой же длины, как i%l=sum.map(^i)l. Делать это более бессмысленно, не помогает. Определяя это как g i=...теряет байты, когда мы называем это. Хотя это %работает для любого списка, но мы вызываем его только со списком проблемных входов, при lкаждом вызове с аргументом не теряется ни одного байта, потому что вызов с двумя аргументами i%lне длиннее, чем вызов с одним аргументом g i.


У нас есть LATЕИксздесь :)
flawr

Мне очень нравится %идея! Это выглядит как дискретная версия статистических моментов .
flawr

1

K (ок) , 33 23 байта

-10 байт благодаря ngn!

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

Попробуйте онлайн!

Первая попытка кодирования (я не смею называть это "игрой в гольф") на K. Я почти уверен, что это можно сделать намного лучше (слишком много имен переменных здесь ...)


1
красивый! вы можете заменить начальное (x-m)на t( tio )
нгн

1
внутренний { }не нужен - его неявное имя параметра есть, xи ему был передан xаргумент as ( tio )
ngn

1
другой -1 байт путем замены x-+/xна x-/x. левый аргумент, -/служащий начальным значением для сокращения ( tio )
нгн

@ngn Спасибо! Теперь я вижу, что первые 2 гольфа очевидны; последний выше моего нынешнего уровня :)
Гален Иванов


1

TI-Basic (серия 83), 14 11 байтов

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

Принимает вход в Ans. Например, если вы введете выше в prgmSTANDARD, то {1,2,3}:prgmSTANDARDвернется {-1.224744871,0.0,1.224744871}.

Ранее я пытался использовать 1-Var Statsкоманду, в которой хранится стандартное отклонение совокупности σx, но это не составляет труда вычислить его вручную.


1

05AB1E , 9 байт

ÅA-DnÅAt/

Порт JavaScript @Arnauld 's answer , так что не забудьте его поддержать!

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

Å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 байт

mc-dJ.OQ@.Om^-Jk2Q2

Попробуйте это онлайн здесь .

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

Изменить: после просмотра ответа Кевина , изменил использовать средние встроенные для внутренних результатов. Предыдущий ответ:mc-dJ.OQ@csm^-Jk2QlQ2


0

SNOBOL4 (CSNOBOL4) , 229 байтов

	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)

Попробуйте онлайн!

Ссылка - на функциональную версию кода, которая создает массив из STDIN, учитывая его длину, а затем его элементы, затем запускает функцию Zи, наконец, выводит значения.

Определяет функцию, Zкоторая возвращает массив.

1.На линии 4 необходимо выполнить арифметические операции с плавающей запятой правильно.



0

Древесный уголь , 25 19 байт

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

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

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

Рассчитать μ и векторизовать вычесть его из каждого Икся,

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

Рассчитать σВекторизованное деление каждого Икся и выведите результат.

Редактировать: Сохранено 6 байтов благодаря @ ASCII-only для a) использования SquareRoot()вместо Power(0.5)b) исправления векторизации Divide()( IntDivide()вместо этого) c) создания Power()векторизации.


зачеркнуто 25 = нет байтов? : P (Кроме того, вы еще не обновили ссылку TIO)
только для ASCII

@ Только для ASCII Ой, спасибо!
Нил
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.