Comment puis-je faire de l'écart type dans Ruby?
J'ai plusieurs enregistrements avec un attribut donné, et je veux trouver l'écart type.
Comment dois-je faire?
Vous devez vous connecter pour publier un commentaire.
J'ai plusieurs enregistrements avec un attribut donné, et je veux trouver l'écart type.
Comment dois-je faire?
Vous devez vous connecter pour publier un commentaire.
De le tester:
01/17/2012:
de fixation "sample_variance" merci à Dave Sag
sample_variance
méthode. Voir ma réponse ci-dessous.sum/(self.length - 1).to_f
pourquoi êtes-vous en soustrayant 1 de la longueur de la Énumérable?return 0.0 if a.length == 1
le début desample_variance
.def sum ; self.inject(:+) ; end
Il semble que Angela peut avoir envie d'une bibliothèque existante. Après avoir joué avec statsample, array-statisics, et quelques autres, je vous recommande la descriptive_statistics gem si vous êtes en essayant d'éviter de réinventer la roue.
Je ne peux pas parler à sa statistique de l'exactitude, ou de votre confort avec le singe de correction Énumérable; mais il est facile à utiliser et facile à contribuer.
NoMethodError: undefined method
zéro?' for nil:NilClass " et(Object doesn't support #inspect)
.La réponse donnée ci-dessus est élégant, mais a une légère erreur. N'étant pas des stats de la tête moi-même je m'assis et lire en détail un certain nombre de sites web et trouvé celui-ci a donné la plus compréhensible explication de comment calculer un écart-type. http://sonia.hubpages.com/hub/stddev
L'erreur dans la réponse ci-dessus est dans le
sample_variance
méthode.Voici ma version corrigée, avec une simple unité de test qui montre que cela fonctionne.
dans
./lib/enumerable/standard_deviation.rb
dans
./test
à l'aide de nombres dérivés à partir d'une simple feuille de calcul.assert result - expected < 1e-10
, a ajoutérequire test/unit
et changé le premier besoin de `besoin 'énumérable'.Je ne suis pas un grand fan de l'ajout de méthodes de
Enumerable
car il pourrait y avoir des effets secondaires indésirables. Il donne également des méthodes de vraiment spécifique à un tableau de nombres à toute classe héritant deEnumerable
, qui n'a pas de sens dans la plupart des cas.Tout c'est très bien pour des tests, des scripts ou des petites applis, c'est risqué pour des applications plus importantes, alors voici une alternative basée sur @tolitius réponse qui était déjà parfait. C'est plus pour la référence que d'autre chose:
Et puis vous l'utilisez en tant que tel:
Le comportement est le même, mais il évite les frais généraux et les risques d'ajouter des méthodes à
Enumerable
.L'présenté le calcul ne sont pas très efficaces, car ils ont besoin de plusieurs (au moins deux, mais souvent trois parce que vous voulez généralement à la moyenne actuelle en plus de std-dev) passe à travers le tableau.
Je sais que Ruby n'est pas l'endroit pour chercher de l'efficacité, mais c'est mon application qui calcule la moyenne et l'écart-type avec un seul passage sur les valeurs de la liste:
inject
et aussi je ne suis pas sûr de ce que vous avez contre le tableau, sauf qu'il crée de n objets, mais elles sont de courte durée, des objets et ne devrait pas être une énorme ressource de vidange.Comme une fonction simple, étant donné une liste de nombres:
Si les dossiers à la main sont de type
Integer
ouRational
, vous pouvez calculer la variance à l'aide deRational
au lieu deFloat
pour éviter les erreurs introduites par l'arrondissement.Par exemple:
(Il serait prudent d'ajouter un cas spécial de manutention pour vider les listes et les autres cas de bord.)
Ensuite la racine carrée peut être définie comme:
Dans le cas où les gens sont à l'aide de postgres ... il fournit des fonctions d'agrégation pour stddev_pop et stddev_samp - postgresql fonctions d'agrégation
stddev (équivalent de stddev_samp) disponible depuis au moins postgres 7.1, depuis 8.2 les deux samp et pop sont fournis.
Ou que diriez-vous: