2012-02-23 97 views
4

numpy.random.uniform()這樣的函數返回兩個邊界之間的浮點值,包括第一個邊界但是不包括最高的一個。也就是說,numpy.random.uniform(0,1)可能會產生0,但不會導致1.如何將浮點數限制在一個極限以下?

我正在採取這樣的數字並使用函數處理它們,有時函數返回範圍之外的結果。我可以使用numpy.clip()將範圍之外的值切回到0-1,但不幸的是,該限制是(包括頂部數字的)。

如何在python中指定「無限小於1的數字」?

+0

如果數學是相信的,你不能。 – 2012-02-23 02:14:39

+2

在大多數系統中有一個epsilon的概念,它是最小的增量 – 2012-02-23 02:15:48

+0

嗯,哦,我可以感覺到一個0.99999 ... <1'火焰戰爭釀造 – wim 2012-02-23 03:33:34

回答

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 2012-02-23 04:30:33

+0

爲什麼'numpy.nextafter(1,0)==(1-sys.float_info.epsilon)'不是這種情況,是因爲浮點密度的變化取決於幅度? – wim 2012-02-23 04:46:04

+0

@wim:是的。 1 + epsilon/2 = 1,但是1-eps/2 = nextafter(1,0)之後。 – DSM 2012-02-23 04:52:22

3

Python的sys提供一種float_info結構與epsilon屬性並且被定義爲與1之間

差至少大於1的值即表示爲一個浮

因此,我想像

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

應該做的伎倆。雖然這通常很糟糕,並且可能有很多原因可能導致您不應該嘗試此操作。

編輯我剛剛觀察到一個這樣的原因 - 執行。雖然CPython可以滿足您的期望,但我的第一個選擇是IronPython,它是doesn't(儘管它是一個bug)。你要警告!

+0

那麼......有沒有一種通常不好的方法? – mattdm 2012-02-23 03:36:10

+1

這真的取決於你爲什麼需要你的函數在[0,1)。你想忽略大於等於1的值嗎?你想把這些值包括在1-eps中嗎?誰在考慮這些價值觀,爲什麼這個人需要他們是[0,1]?你聲明存在一個返回[0,1)的庫函數。然後你f(u())這些數字並返回[0,inf),但是想返回[0,1)...爲什麼?據推測有一個h(f(u)),也許我們應該關注h。 :) – Gleno 2012-02-23 05:21:37

1

在大多數實際情況下,您不需要無限縮小,您可以近似它。所以對於你的例子,我會使用0.9999999而不是1.0。

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)是有效的在做什麼?

如果您的處理正在返回超出有效範圍的值並且是確定性的,那麼您可能應該過濾輸入而不是剪切輸出。