calculer la moyenne et la variance avec une itération
J'ai un itérateur de nombres, par exemple, un fichier objet:
f = open("datafile.dat")
maintenant, je veux calculer:
mean = get_mean(f)
sigma = get_sigma(f, mean)
Quelle est la meilleure mise en œuvre? Supposons que le fichier est gros et je voudrais éviter de le lire deux fois.
Voulez-vous éviter de lire le fichier deux fois, ou d'éviter de l'itération deux fois?
Je ne crois pas que tu nous montre le code complet. Vous êtes de passage d'un fichier à
Pourquoi avez-vous besoin de placer une restriction relative à la modification de la fonction? Si vous réarrangé la formule de la variance, je pense que vous pouvez obtenir en quelque chose comme sqrt(1/(n-1)*(sum(li**2 pour li en l) + nmmsomme(li pour li en l) + n*mm)) où n est len(l). C'est, si mon calcul est correct. Ensuite, vous pouvez parcourir une fois, le calcul de la somme des termes ci-dessus refactoring et la moyenne en même temps.
vous avez raison, j'ai reformulé la question
quelle est la taille de votre fichier?
Je ne crois pas que tu nous montre le code complet. Vous êtes de passage d'un fichier à
get_mean()
où fsum()
accepte uniquement des listes de numéros.Pourquoi avez-vous besoin de placer une restriction relative à la modification de la fonction? Si vous réarrangé la formule de la variance, je pense que vous pouvez obtenir en quelque chose comme sqrt(1/(n-1)*(sum(li**2 pour li en l) + nmmsomme(li pour li en l) + n*mm)) où n est len(l). C'est, si mon calcul est correct. Ensuite, vous pouvez parcourir une fois, le calcul de la somme des termes ci-dessus refactoring et la moyenne en même temps.
vous avez raison, j'ai reformulé la question
quelle est la taille de votre fichier?
OriginalL'auteur Ruggero Turra | 2010-02-26
Vous devez vous connecter pour publier un commentaire.
Si vous souhaitez effectuer une itération une fois, vous pouvez écrire votre fonction somme:
et utiliser le résultat dans votre
sigma
fonction.Modifier: maintenant, vous pouvez calculer l'écart comme ceci: (s2 - (s*s) /N) /N
Par la prise en compte de @Adam de Bowen commentaire,
gardez à l'esprit que si nous utilisons les mathématiques astuces et de transformer les formules originales
on peut dégrader les résultats.
s/n
et la variance ests2/n - mean*mean
c'est-à-dire, la moyenne des carrés moins le carré de la moyenne. Cependant, vous devez être conscient que le calcul de la variance de cette façon peuvent être inexacts pour n grand en raison de la différence d'échelle entre s2 et e*e lors de l'accumulation. Malheureusement, cela signifie que pour n grand la passe de deux algorithme est beaucoup plus précis (et un meilleur choix).Bowen, merci. J'ai oublié de le mentionner.
Cette réponse est référencé dans PEP 450 comme étant des conseils pour une approche naïve, à la détermination des écarts avec les pauvres, la stabilité et la précision de ses caractéristiques. Voir pour comparaison de la variance des fonctions dans le projet de Python 3.4+
statistics
module.merci, je n'étais pas au courant de cela. Ma réponse montre comment calculer la moyenne et la variance avec une itération, et il pourrait être amélioré pour gérer les flotteurs et être plus précis. PEP de 450 références de ma réponse, bien que le calcul est fait avec un algorithme différent.
OriginalL'auteur Nick Dandoulakis
Je pense que Nick D a la réponse correcte.
En supposant que vous voulez calculer la moyenne et la variance en un seul balayage du fichier (et vous n'avez pas vraiment besoin de deux fonctions qui doivent être appelés l'un après l'autre), vous pouvez collecter la somme des valeurs et de leurs places et leur utilisation de telles sommes (associé au nombre de lecture des éléments), pour le calcul dans le même temps, la moyenne et la variance.
Il y a quelques numérique des problèmes de stabilité, mais l'idée en
http://en.wikipedia.org/wiki/Computational_formula_for_the_variance
est l'ingrédient de base dont vous avez besoin. Plus de détails sont à
http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
où je vous suggère de lire les "Naïfs algorithme".
Espère que cette aide,
Massimo
OriginalL'auteur Mapio
Faire une liste à partir de l'itératif, ou de l'utilisation
itertools.tee()
.maintenant, je sais enfin comment je peux faire codeblock avec un lien
t1, t2 = tee(...)
ne vaut pas le coup si vous voulez consommer de l'ensemble de lat1
première et toutt2
plus tard. Dans de tels cas, l'utilisationlist(seq)
et itérer sur queOriginalL'auteur Ignacio Vazquez-Abrams
Vous pouvez calculer les deux en un seul passage. Voir:
http://www.johndcook.com/standard_deviation.html
OriginalL'auteur jxz
Je ne suis pas sûr qu'il ya beaucoup de choix.
Vous à la parcourir vos numéros deux fois en tout cas que l'écart-type nécessitera l'information moyenne sur chaque valeur.
Si vous avez assez de mémoire, vous pouvez gagner de l'I/O accès par le chargement de votre fichier dans la mémoire lors de la première itération, mais qui n'est pas le sujet de l'OMI.
OriginalL'auteur Benoit Vidis
Car j'ai l'impression qu'il y a de bons éléments dispersés dans de multiples réponses, je voudrais résumer:
Si votre fichier est trop grand pour équiper convenablement en mémoire, et si vous voulez une bonne précision dans l'écart, vous avez besoin de lire le fichier deux fois (avec un seul passage, l'écart est la différence entre les deux grands nombres, ce qui n'est pas précis à cause de la virgule flottante limitations). Notez que votre système d'exploitation est susceptible de fournir certaines automatique de la vitesse pour la deuxième lecture du fichier, qu'il peut encore être en RAM lors de la seconde passe.
Si vous n'avez pas de soins pour la précision de la variance, vous pouvez simplement itérer une fois sur le fichier et de calculer les quantités suggérées par Nick d', avec les informations fournies dans le commentaire d'Adam Bowen.
OriginalL'auteur Eric Lebigot
Vous avez deux solutions
Faire une liste de votre itérateur et boucle autant de fois que vous le souhaitez. Inconvénient est que tout ce qui sera dans la mémoire, donc ne convient pas si votre fichier est gros. L'utilisation Simple de la itertools.té aussi ne vous sauvera pas
Il n'y a pas d'autre solution , sauf , vous n'avez pas besoin de passer la sortie de get_mean à get_sigma, parce que dans ce cas ils ne peuvent être que dans la série, mais si vous supprimer cette restriction, alors vous pouvez exécuter les deux fonctions en parallèle à l'aide de threads, et l'utilisation itertools.tee-shirt à deux itérateurs d'un
OriginalL'auteur Anurag Uniyal
Vous pouvez utiliser la carte de réduire dans une élégante façon
de l'échantillon est la liste que vous souhaitez obtenir de sa variance
de l'échantillon = [a,b,c, ...]
Dans un succincte ligne de code:
sum(sample) / len(sample)
et similaires pour la variance. Le gros point fort ici, vous êtes à l'itération deux fois sur mon fichier. Ma question posée pour une itérationoups!- oui, vous avez raison. Mais c'est un bon prétexte pour utiliser les fonctions lambda =)
OriginalL'auteur Juan