2012-02-23 18 views
4

numpy.random.uniform()のような関数は、最初の境界を含めての2つの境界の間で浮動小数点値を返します.を除きます。つまり、numpy.random.uniform(0,1)は0を返すことがありますが、決して1になりません。浮動小数点数を制限値以下にクリップするにはどうすればよいですか?

私はこのような数をとって、範囲外の結果を返す関数で処理しています。 numpy.clip()を使用して範囲外の値を0-1に切り捨てることはできますが、残念ながらその上限はを含めて先頭番号のです。

pythonで「1より小さい数値」を指定するにはどうすればよいですか?

+0

数学が信じられなければ、あなたは信じられません。 –

+2

ほとんどのシステムでは、最も小さなインクリメントであるイプシロンのコンセプトがあります –

+0

ああ、私は0.99999 ... <1の炎の醸造を感じることができます – wim

答えて

5

さて、あなたがnumpyのを使用している場合、あなたは、単にnumpy.nextafterを使用することができます。

>>> import numpy 
>>> numpy.nextafter(1, 0) 
0.99999999999999989 

注意(少なくとも私にとっては)それ:

ちなみに
>>> import sys 
>>> 1-sys.float_info.epsilon 
0.9999999999999998 
>>> numpy.nextafter(1, 0) - (1-sys.float_info.epsilon) 
1.1102230246251565e-16 
>>> numpy.nextafter(1, 0) > (1-sys.float_info.epsilon) 
True 

、二@Robertカーンのポイントへそれはときどきrandom.uniform となりますは、(0,1)以外の入力の上限を含みます:

>>> import random, numpy 
>>> numpy.nextafter(0,1) 
4.9406564584124654e-324 
>>> random.uniform(0, numpy.nextafter(0,1)) 
0.0 
>>> random.uniform(0, numpy.nextafter(0,1)) 
0.0 
>>> random.uniform(0, numpy.nextafter(0,1)) 
4.9406564584124654e-324 

[一般的に、この問題に近づけるより良い方法があると思います。]

+0

クール、決してそれについて知りませんでした! – wim

+0

なぜnumpy.nextafter(1,0)==(1-sys.float_info.epsilon) 'は浮動小数点の密度が大きさによって変わるのでしょうか? – wim

+0

@wim:うん。 1 +ε/ 2 = 1であるが、1-eps/2 =次の(1,0)となる。 – DSM

3

Pythonのsysepsilon属性でfloat_info構造体を提供し、

1との違いと

だから私が思うだろうfloatとして表現可能である1より大きい少なくとも値として定義されます何かのような

def clip(num): 
    if(num >= 1): 
     return 1 - sys.float_info.epsilon 
    return num 

トリックを行う必要があります。これは一般的に悪いですが、これを決して試みてはいけない理由はたくさんあります。

EDIT私はちょうど1つのそのような理由 - 実装を見ました。 CPythonはあなたが期待していることを実行しますが、私の最初の選択肢はIronPythonです。これはdoesn'tです(バグですが)。あなたに警告してください!

+0

そういうわけではありません。 – mattdm

+1

本当にあなたの機能がなぜ[0、1]にある必要があるのか​​によって決まります。値> = 1を無視しますか?これらの値を1 - epsとして含めるかしますか?誰がその価値観を取っているのですか?その男がなぜ彼らに[0,1]が必要なのでしょうか?あなたは[0、1]を返すライブラリ関数uが存在すると述べています。次に、これらの数値をf(u())返して[0、inf]を返しますが、[0、1]を返したいと思います...なぜですか?おそらくh(f(u))があり、おそらくhに焦点を当てるべきです。 :) – Gleno

1

ほとんどの実際のケースでは、極小にする必要はありませんが、近似できます。あなたの例では、1.0の代わりに0.9999999を使用します。

0

私はあなたの使用例をよく理解していません。最初の場所で一様乱数ジェネレータがエンドポイントを返すことを望まないという問題はありますか?そして、あなたは自分自身の発電機でそれをラップすることができます:

def my_uniform(low=0, high=1): 
    import numpy as np 
    while True: 
    x = np.random.uniform(low, high) 
    if x > low and x < high: 
     yield x 

そうでない場合、あなたは1が無効であるが、np.nextafter(1, 0)が有効である出力で何をしているの?

処理で有効な範囲外の値が返され、確定的な場合は、出力をクリップするのではなく入力をフィルタリングする必要があります。

関連する問題