2014-05-07 1 views
3

J'ai besoin d'une fonction ne renvoyant que la partie significative d'une valeur par rapport à une erreur donnée. Signification quelque chose comme ceci:Nombre significatif de chiffres de valeur par son erreur

def (value, error): 
    """ This function takes a value and determines its significant 
     accuracy by its error. 
     It returns only the scientific important part of a value and drops the rest. """ 

    magic magic magic.... 

    return formated value as String. 

Ce que je l'ai écrit à ce jour pour montrer ce que je veux dire:

import numpy as np 

def signigicant(value, error): 
    """ Returns a number in a scintific format. Meaning a value has an error 
     and that error determines how many digits of the 
     value are signifcant. e.g. value = 12.345MHz, 
     error = 0.1MHz => 12.3MHz because the error is at the first digit. 
     (in reality drop the MHz its just to show why.)""" 


    xx = "%E"%error # I assume this is most ineffective. 
    xx = xx.split("E") 
    xx = int(xx[1]) 

    if error <= value: # this should be the normal case 
     yy = np.around(value, -xx) 

     if xx >= 0: # Error is 1 or bigger 
      return "%i"%yy 

     else: # Error is smaller than 1 
      string = "%."+str(-xx) +"f" 
      return string%yy 

    if error > value: # This should not be usual but it can happen. 
     return "%g"%value 

Ce que je ne veux pas est une fonction comme numpys autour ou rond. Ces fonctions prennent une valeur et veulent savoir quelle partie de cette valeur est importante. Le fait est qu'en général je ne sais pas combien de chiffres sont significatifs. Cela dépend de la taille de l'erreur de cette valeur. Un autre exemple:

valeur = 123, erreur = 12, => 120 On peut laisser tomber le 3, car l'erreur est à la taille 10. Toutefois, ce comportement n'est pas si important, parce que certaines personnes écrivent encore 123 pour la valeur. Ici c'est correct mais pas parfaitement correct.

Pour les grands nombres, l'opérateur de chaîne "g" est un choix utilisable mais pas toujours ce dont j'ai besoin. Par exemple Si l'erreur est plus grande que la valeur. (Se produit par exemple quand quelqu'un veut mesurer quelque chose qui n'existe pas.)

valeur = 10, erreur = 100

Je souhaite toujours garder 10 la valeur parce que je le savais mieux. La fonction devrait retourner 10 alors et non 0.

Les choses que j'ai écrites fonctionnent plus ou moins, mais elles ne sont en aucun cas efficaces ou élégantes. Je suppose également que cette question concerne des centaines de personnes, car chaque scientifique doit formater les nombres de cette façon. Donc je suis sûr qu'il y a une solution prête à l'emploi quelque part mais je ne l'ai pas encore trouvée. Probablement mes compétences google ne sont pas assez bon, mais je n'ai pas été en mesure de trouver une solution à cela en deux jours et maintenant je demande ici.

Pour tester mon code, j'ai utilisé ce qui suit, mais plus est nécessaire.

errors = [0.2,1.123,1.0, 123123.1233215,0.123123123768] 
values = [12.3453,123123321.4321432, 0.000321 ,321321.986123612361236,0.000] 

for value, error in zip(values, errors): 
print "Teste Value: ",value, "Error:", error 
print "Result: ", signigicant(value, error) 
+2

AFAIK, pour le calcul scientifique, ne vous contentez pas ignorer l'erreur. Si une valeur est imprécise, elle est généralement indiquée par ex. 12,345 MHz ± 0,1 MHz. – nneonneo

Répondre

1
import math 

def round_on_error(value, error): 
    significant_digits = 10**math.floor(math.log(error, 10)) 
    return value // significant_digits * significant_digits 

Exemple:

>>> errors = [0.2,1.123,1.0, 123123.1233215,0.123123123768] 
>>> values = [12.3453,123123321.4321432, 0.000321 ,321321.986123612361236,0.000] 
>>> map(round_on_error, values, errors) 
[12.3, 123123321.0, 0.0, 300000.0, 0.0] 

Et si vous voulez garder une valeur qui est inférieure à son erreur

if (value < error) 
    return value 
else 
    def round_on_error(value, error): 
    significant_digits = 10**math.floor(math.log(error, 10)) 
    return value // significant_digits * significant_digits 
Questions connexes