2013-05-10 126 views
2

隨機數我想0和0.5之間產生均勻分佈的隨機數,但截短至2個小數位。產生截斷到小數點後2位

沒有截斷,我知道這是由

import numpy as np 
rs = np.random.RandomState(123456) 
set = rs.uniform(size=(50,1))*0.5 

任何人都可以幫助我與建議,就如何生成隨機數高達2 D.P.只要?謝謝!

+3

您是否知道小數'0.1' *不存在*爲'float'? – 2013-05-10 21:22:31

+0

是的,我相信我應該澄清一點,我希望四捨五入到兩位有效數字。 (在數值精度範圍內) – mtigger 2013-05-10 21:31:24

+3

@mtigger:我認爲你錯過了這一點。如果將'0.10'舍入到2個有效數字並將其存儲在'float'(或numpy'f8')中,則會得到'0.100000000000000005551115'。而下一個較小的'浮動'小於'0.10'。在IEEE雙倍中沒有等於'0.10'的值。 – abarnert 2013-05-10 21:33:44

回答

4

A float不能被截斷(或四捨五入)爲2個十進制數字,因爲有許多具有2個十進制數字的值不能完全表示爲IEEE double。

如果你真的想你說的話你想要的,你需要使用一類具有精確的精度,像Decimal

當然,這樣做有缺點 - numpy用戶最明顯的一個問題就是您必須使用dtype=object,並且具有所有的緊湊性和性能影響。

但它實際做你問什麼的唯一途徑。

最有可能的,你居然做什麼或者是Joran比斯利的答案(離開他們未截短的,只是輪在打印輸出時)或類似Lauritz五Thaulow的答案東西(得到最接近你可以,然後在任何地方使用明確的epsilon檢查)。

或者,您可以按照David Heffernan在評論中所建議的那樣進行隱式定點算術:生成0到50之間的隨機整數,將它們保留爲整數numpy,並將它們格式化爲定點小數和/必要時輸入Decimal(例如,打印結果)。這爲您提供Decimal的所有優勢,但不會帶來成本......雖然它確實打開了一個明顯的窗口,通過忘記在某處放置2個位置來創建新的錯誤。

+0

謝謝,這清除了我對浮點數和小數的一些誤解。 – mtigger 2013-05-10 21:35:38

+2

@mtigger:這是[每個計算機科學家應該知道的浮點算術知識]的必需鏈接(http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)。 – abarnert 2013-05-10 21:36:44

3

小數不會被截斷到小數點後2位曾經......但他們的字符串表示也許

import numpy as np 
rs = np.random.RandomState(123456) 
set = rs.uniform(size=(50,1))*0.5 

print ["%0.2d"%val for val in set] 
+2

'Decimal's _ can be_ truncated to 2 decimal places;它是'浮動',不能。 – abarnert 2013-05-10 21:24:17

+0

meh語義:P(但是我知道十進制是一個確切的表示類型:P) – 2013-05-10 21:25:08

1

這個怎麼樣?

np.random.randint(0, 50, size=(50,1)).astype("float")/100 

也就是說,通過創建0和50,和鴻溝之間的隨機整數100

編輯:

正如在評論中明確表示,這不會給你確切的由於內存中浮點表示的性質,需要使用兩位小數。它可能看起來像你有你的數組中的確切浮動0.1,但它絕對是不準確0.1。但非常非常近,你可以得到更接近使用「雙」的數據類型來代替。

您可以通過只維持數作爲整數推遲這一問題,並記住他們是你使用的時候要除以100。

hundreds = random.randint(0, 50, size=(50, 1)) 

則至少舍入不會發生,直到最後一分鐘(或者根本沒有,如果公式的分子是分母的倍數)。

+2

浮動行爲並不能保證只有兩個小數位在這裏... – 2013-05-10 21:20:16

+0

@Joran哇,這是快速反饋。你測試過了嗎?我的測試全部只返回兩位或一位小數。 – 2013-05-10 21:21:31

+0

是的!我只是在嘗試。謝謝! – mtigger 2013-05-10 21:21:33

0

我設法找到了另一種選擇:

import numpy as np 
rs = np.random.RandomState(123456) 
set = rs.uniform(size=(50,2)) 
for i in range(50): 
    for j in range(2): 
     set[i,j] = round(set[i,j],2) 
+0

爲什麼不使用'np.around(rs.uniform(size =(50,2))* 0.5,decimals = 2)'那麼?它的速度更快,工作原理相同,並且具有與我的解決方案相同的技術缺陷,正如[文檔]中所述(http://docs.scipy.org/doc/numpy/reference/generated/numpy.around.html #numpy.around):*由於IEEE浮點標準*中小數部分的不精確表示,結果也可能令人驚訝。 – 2013-05-12 20:36:33