2011-07-12 10 views
7

私はnumpy、scipy、matplotlibでpythonを使ってデータを評価しています。結果として、私は平均値とフィッティングパラメータをエラーバーで得る。python - pretty print errorbars

私は、pythonがこのデータを与えられた精度に従って自動的にきれいに印刷したいと思います。例:

結果がx = 0./- 0.000123であるとします。 精度2を指定した場合、これを自動的に1.235(12) x 10^-2とフォーマットする方法はありますか?つまり、値ではなくエラーバーの精度を数えます。

このような機能を提供するパッケージを知っている人はいますか、それとも自分で実装する必要がありますか?

これをPython文字列フォーマット機構に挿入する方法はありますか?私。 "%.2N" % (0., 0.0000123)のようなものを書くことができます。

私はすでにnumpyとscipyのドキュメントを見て回っていましたが、何も見つかりませんでした。統計を扱う人にとっては、これは便利な機能だと思います。

ありがとうございました!

EDIT: 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) 

10の累乗は、わかりやすくするために省略されています。 カッコ内の数字は、標準エラーの省略表記です。括弧の前の数字の最後の桁と括弧内の数字の最後の桁は同じ小数の桁でなければなりません。なんらかの理由で私はこの概念をオンラインでよく説明することはできません。私が得たのはこのドイツのウィキペディアの記事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'の略記です。元の数値「0.」は、標準誤差で2の指定された精度のために丸められます。数字「0.000123」は私の結果の標準エラーです。元の投稿にいくつかの例を追加します。 – Lemming

答えて

2

x +- yは(それが実部と虚との複合体として見ることができる標準タイプではありませんので、 xとyiの推測と同様ですが、これは単純化されません...)しかし、型を作成して文字列関数をオーバーライドすることでプレゼンテーションを完全に制御することができます。つまり、

あなたは自然に __str__関数の内部で、もう少し派手な何かができる
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) 

...

+0

ありがとう、それはフォーマット文字列部分の始まりです。あなたは引数を渡す方法を知っていますか?私。 ''%.4f ''の '.4'にあります。私は自分自身の略記を実装しました、EDIT2を見てください。 – Lemming

+0

こんにちは、それはおそらくあなた自身のかなりのプリンタを書くための最良の解決策です。 – bjarneh

+0

あなたの応答は完全には読まれませんでした。そうであれば、 'somenumber'が' + - 'の数字の数に基づいているならば 'fmstr ="%.df "%(somenumber)あなたが思っているように、これはうまくいくはずです – bjarneh