2011-07-12 81 views
7

我用numpy,scipy和matplotlib進行數據評估。作爲結果我獲得平均值和擬合參數與錯誤條。蟒蛇 - 漂亮的打印錯誤欄

我希望python根據給定的精度自動漂亮地打印這些數據。例如:

假設我得到結果x = 0./- 0.000123。 當指定精度爲2時,是否有方法將其自動格式化爲1.235(12) x 10^-2。也就是說,計算錯誤欄中的精度,而不是數值。

有沒有人知道提供這種功能的軟件包,還是我必須自己實現?

有沒有辦法將其注入到python字符串格式化機制?即能夠寫出類似"%.2N" % (0., 0.0000123)的東西。

我已經瀏覽了numpy和scipy的文檔並搜索了一下,但是我找不到任何東西。我認爲這對於處理統計數據的每個人都是一個有用的功能。

感謝您的幫助!

編輯: 按照Nathan Whitehead的要求,我會舉幾個例子。

123 +- 1   ----precision 1-----> 123(1) 
123 +- 1.1  ----precision 2-----> 123.0(11) 
0.- 0.001 ----precision 1-----> 0.012(1) 
123.111 +- 0.123 ----precision 2-----> 123.11(12) 

爲清楚起見省略了十的冪次。 括號內的數字是標準錯誤的簡寫符號。編號前的數字的最後一位和編號內的編號的最後一位必須是相同的小數位數。出於某種原因,我無法在網上找到這個概念的很好的解釋。我唯一得到的是這個德國維基百科文章here。但是,這是一個非常常見和非常方便的符號。

EDIT2: 我實現了速記符號的事情自己:

#!/usr/bin/env python 
# *-* coding: utf-8 *-* 

from math import floor, log10 

# uncertainty to string 
def un2str(x, xe, precision=2): 
    """pretty print nominal value and uncertainty 

    x - nominal value 
    xe - uncertainty 
    precision - number of significant digits in uncertainty 

    returns shortest string representation of `x +- xe` either as 
     x.xx(ee)e+xx 
    or as 
     xxx.xx(ee)""" 
    # base 10 exponents 
    x_exp = int(floor(log10(x))) 
    xe_exp = int(floor(log10(xe))) 

    # uncertainty 
    un_exp = xe_exp-precision+1 
    un_int = round(xe*10**(-un_exp)) 

    # nominal value 
    no_exp = un_exp 
    no_int = round(x*10**(-no_exp)) 

    # format - nom(unc)exp 
    fieldw = x_exp - no_exp 
    fmt = '%%.%df' % fieldw 
    result1 = (fmt + '(%.0f)e%d') % (no_int*10**(-fieldw), un_int, x_exp) 

    # format - nom(unc) 
    fieldw = max(0, -no_exp) 
    fmt = '%%.%df' % fieldw 
    result2 = (fmt + '(%.0f)') % (no_int*10**no_exp, un_int*10**max(0, un_exp)) 

    # return shortest representation 
    if len(result2) <= len(result1): 
     return result2 
    else: 
     return result1 


if __name__ == "__main__": 
    xs = [123456, 12.34567, 0.123456, 0.0, 0.000] 
    xes = [ 123, 0.00123, 0.000123, 0.000000, 0.00000] 
    precs = [  1,  2,  3,    4,   1] 

    for (x, xe, prec) in zip(xs, xes, precs): 
     print '%.6e +- %.6e @%d --> %s' % (x, xe, prec, un2str(x, xe, prec)) 

輸出:

1.234560e+05 +- 1.230000e+02 @1 --> 1.235(1)e5 
1.234567e+01 +- 1.230000e-03 @2 --> 12.3457(12) 
1.234560e-01 +- 1.230000e-04 @3 --> 0.123456(123) 
1.234560e-03 +- 1.234500e-08 @4 --> 0.0(1235) 
1.234560e-05 +- 1.234000e-07 @1 --> 1.23(1)e-5 
+1

你能舉些例子?我不明白「1.235(12)x 10^-2」是什麼意思,以及它如何與「0.」和「0.000123」連接。 –

+0

當然,'1.235(12)x 10^-2'是'1.235 x 10^-2 + - 0.0012 x 10^-2'的簡寫符號。由於標準誤差的指定精度爲2,原始數字「0.」被舍入。數字「0.000123」是我的結果的標準錯誤。我會在原文中增加幾個例子。 – Lemming

回答

2

因爲x +- y不是標準型(它可以被看作是具有實部和虛複雜作爲x和yi的猜測,但這並不能簡化任何東西......),但是你可以通過創建一個類型並重寫字符串函數來完全控制演示文稿,即像這樣的東西

class Res(object): 
    def __init__(self, res, delta): 
    self.res = res 
    self.delta = delta 

    def __str__(self): 
    return "%f +- %f"%(self.res,self.delta) 

if __name__ == '__main__': 
    x = Res(0.2710,0.001) 
    print(x) 
    print(" a result: %s" % x) 

你自然可以做一些事情的__str__函數中多一點花哨......

+0

謝謝,這是格式化字符串部分的開始。你知道一種傳遞參數的方式嗎?即在''。%4f''.4'中。我自己實現了速記符號,請參閱EDIT2。 – Lemming

+0

嗨,是啊,這可能是最好的解決方案,寫你自己漂亮的打印機.. – bjarneh

+0

抱歉沒有完全讀到你的迴應,是的,你也可以動態地格式化字符串,'fmstr =「%.df」%(somenumber)'如果'somenumber'是基於'+ - '部分,這應該按照我的想法工作 – bjarneh