2012-04-04 12 views
14

私はforループの反復を定義し、予期しない結果を得るためにarange関数を使用しています。python numpy予期しない結果

i = arange(7.8,8.4,0.05) 
print i 

次のyeilds:

i = arange(7.8,8.35,0.05) 

[ 7.8 7.85 7.9 7.95 8. 8.05 8.1 8.15 8.2 8.25 8.3 ] 

を生み出すしかし、私は私の範囲がしたいが、以下のように、まだ8.35のストップ値を使用して

[ 7.8 7.85 7.9 7.95 8. 8.05 8.1 8.15 8.2 8.25 8.3 8.35 8.4 ] 

8.35で終了! 8.35を超えるストップ値と< 8.4を使用して私の結果を得ることができるのは分かっていますが、それはどうして違っていて、矛盾しているのですか?

編集:私は、私はあなたが浮動小数点の丸めの効果を見ていることを推測しているバージョン2.7

+0

? –

+0

私は2.7を使用しています! – smashtastic

+0

これらの問題を回避する簡単な方法は 'arrange =(7.8,8.351,0.05)'を使用することです。 – Thiru

答えて

9

で2.7

>>> float(repr(2.3)) 
2.3 

は、おそらくそれは、浮動小数点数の制限に関係しています。マシンの精度のために考えられるすべての値を浮動小数点として完全に保存することはできません。たとえば、次の浮動小数点として8.35がほんの少し小さいながら

>>> 8.4 
8.4000000000000004 
>>> 8.35 
8.3499999999999996 

そこで、浮動小数点として8.4は、8.4の実際の値よりもわずかに大きいです。

+1

これはPython 2.6で出力されているようですが、2.7では>>> 8.4が8.4として出てきます – avasal

+3

それは興味深いです。浮動小数点数の印刷方法を変更したようですが、Python 2.6と2.7の浮動小数点数の16進数値を比較すると、同じ(わずかに間違っています)という根本的な数字が表示されます。 –

+0

私はこれが私が何を見ているのかを説明すると思います - ありがとう! – smashtastic

18

を使用しています。

numpy.arangeは、Pythonのrangeと同じことを行います。「エンドポイント」は含まれません。 (例えば、range(0, 4, 2)は、[0,2,4]の代わりに[0,2]を生成します)

ただし、浮動小数点ステップの場合、丸め誤差は累積され、最終値に実際にエンドポイントが含まれることがあります。 arangeのドキュメントに記載されているように

、例えば0.1を非整数のステップを使用して、結果はしばしばない 一貫あろう。これらの場合にはlinspaceを使用する方が良いです。

numpy.linspaceは、開始点と終了点の間に指定された数の点を生成します。ちなみに、デフォルトではエンドポイントも含まれます。

+0

こんにちは - 私はlinspace用のオンラインヘルプを探しましたが、それは不思議な空白です...あなたは適切なリンクを持っていますか? – smashtastic

+1

http://docs.scipy.org/doc/numpy-1.6.0/reference/generated/numpy.linspace.html代わりに 'pydoc numpy.linspace'を実行することもできますし、Pythonインタプリタ' help(numpy.linspace) '、' ipython'では 'numpy.linspace?'だけです。 –

+0

これはドキュメントではっきりしていますが、numpy.arangeは役に立ちますか? – marbel

3

arange機能のヘルプは、Python 2.7用

For floating point arguments, the length of the result is 
    ``ceil((stop - start)/step)``. Because of floating point overflow, 
    this rule may result in the last element of `out` being greater 
    than `stop`. 

を言い、浮動小数点数と文字列の間の変換が正しくほとんどのプラットフォーム上で丸くなっています。 2.6

>>> float(repr(2.3)) 
2.2999999999999998 
1

私は同じ問題を抱えていたと私はnumpy.arangeと、この丸め問題を修正するために私自身の機能を実装:どのPythonのバージョンを使用している

import numpy as np 
def my_arange(a, b, dr, decimals=6): 
    res = [a] 
    k = 1 
    while res[-1] < b: 
     tmp = round(a + k*dr,decimals) 
     if tmp > b: 
      break 
     res.append(tmp) 
     k+=1 

    return np.asarray(res) 
+0

これは役に立ちました。ありがとう! – marbel