2012-04-04 40 views
14

Tôi đang sử dụng chức năng arange để xác định vòng lặp lặp của tôi và nhận được kết quả không mong muốn.python numpy arange kết quả bất ngờ

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

yeilds sau:

[ 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 ] 

chưa sử dụng giá trị dừng 8,35 như sau

i = arange(7.8,8.35,0.05) 

mang lại những điều sau

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

Nhưng tôi muốn phạm vi của tôi để kết thúc lúc 8,35! Tôi biết tôi có thể sử dụng giá trị dừng> 8.35 và < 8.4 để đạt được kết quả của mình, nhưng tại sao lại khác và trong tâm trí của tôi, không nhất quán?

Chỉnh sửa: Tôi đang sử dụng phiên bản 2.7

+0

Phiên bản nào của Python bạn đang sử dụng? –

+0

Tôi đang sử dụng 2,7! – smashtastic

+0

Một cách đơn giản để thoát khỏi những vấn đề này là sử dụng 'sắp xếp = (7.8,8.351,0.05)' – Thiru

Trả lời

9

Có lẽ nó đã làm với những hạn chế về số dấu chấm động. Do độ chính xác của máy, không thể lưu trữ mọi giá trị có thể tưởng tượng một cách hoàn hảo như một điểm nổi. Ví dụ:

>>> 8.4 
8.4000000000000004 
>>> 8.35 
8.3499999999999996 

Vì vậy, 8.4 dưới dạng dấu phẩy hơi lớn hơn giá trị thực của 8,4, trong khi 8,35 dưới dạng dấu phẩy hơi nhỏ hơn một chút.

+1

điều này dường như đầu ra với python 2,6 nhưng với 2,7, >>> 8,4 đi ra như 8.4 – avasal

+3

Vì vậy, nó không, đó là thú vị. Dường như họ đã thay đổi cách in nổi, mặc dù số lượng cơ bản vẫn giống nhau (hơi không chính xác), bạn có thể thấy bằng cách so sánh các giá trị hex cho các phao trong Python 2.6 và 2.7. –

+0

Tôi đoán điều này giải thích những gì tôi thấy - cảm ơn! – smashtastic

18

Tôi đoán rằng bạn đang thấy tác động của làm tròn điểm nổi.

numpy.arange thực hiện tương tự như python's range: Nó không bao gồm "điểm cuối". (ví dụ: range(0, 4, 2) sẽ mang lại [0,2] thay vì [0,2,4])

Tuy nhiên, đối với các bước dấu phẩy động, lỗi làm tròn được tích lũy và đôi khi giá trị cuối cùng thực sự sẽ bao gồm điểm cuối.

Như đã đề cập trong tài liệu cho arange:

Khi sử dụng một bước phi nguyên, chẳng hạn như 0.1, kết quả sẽ thường không phải nhất quán. Tốt hơn là sử dụng linspace cho những trường hợp này.

numpy.linspace tạo số điểm được chỉ định giữa điểm bắt đầu và điểm kết thúc. Ngẫu nhiên, nó bao gồm các thiết bị đầu cuối theo mặc định.

+0

hi - Tôi đã cố gắng tìm tài liệu trợ giúp trực tuyến cho linspace nhưng nó là kỳ lạ trống ... bạn có một liên kết phù hợp không ? – smashtastic

+1

http://docs.scipy.org/doc/numpy-1.6.0/reference/generated/numpy.linspace.html Cách khác, bạn có thể thực hiện 'pydoc numpy.linspace' hoặc nếu bạn đang ở trong trình thông dịch trăn' help (numpy.linspace) ', hoặc trong' ipython', nó chỉ là 'numpy.linspace?'. –

+0

rõ ràng trong tài liệu, nhưng nó không làm cho numpy.arange hữu ích không? – marbel

3

sự giúp đỡ của chức năng arange nói

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`. 

cho python 2.7, Chuyển đổi giữa các số dấu chấm động và chuỗi đang làm tròn một cách chính xác trên hầu hết các nền tảng.

trong 2,7

>>> float(repr(2.3)) 
2.3 

trong 2,6

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

tôi đã cùng một vấn đề và tôi thực hiện chức năng của mình để sửa chữa cho vấn đề làm tròn này với numpy.arange:

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

điều này hữu ích. cảm ơn! – marbel

Các vấn đề liên quan