2017-11-21 8 views
1

파이썬 numpy에서 생성 된 간격 범위가 있습니다. 값은 예상대로이지만 배열을 list로 변환하면 배열의 값과 같지 않습니다.NumPy 배열을리스트로 변환 할 때의 부동 소수점 불일치

numpy.linspace(0.3,0.7,5) 
array([ 0.3, 0.4, 0.5, 0.6, 0.7]) 

numpy.linspace(0.3,0.7,5).tolist() 
[0.3, 0.39999999999999997, 0.5, 0.6, 0.7] 

list(numpy.linspace(0.3,0.7,5)) 
[0.29999999999999999,0.39999999999999997,0.5,0.59999999999999998, 
0.69999999999999996] 

왜 numpy는 이와 같이 동작합니까? 목록의 값을 반올림하기 위해 다른 루프를 사용하지 않고 배열의 값을 배열과 동일하게 유지할 수 있습니까?

이 때문에 데이터 유형 및 각 유형의 대응 __repr__ 구현 될 일

답변

4

: 첫 번째 경우

l = numpy.linspace(0.3,0.7,5).tolist() 

[type(x) for x in l] 
[float, float, float, float, float] 

tolist 누구 __repr__ 구현 자동 부동 절단 파이썬 float 객체 각각 np.float 오브젝트, 변환 포인트 번호는 Gay algorithm에 따릅니다. OTOH :

l = list(numpy.linspace(0.3,0.7,5)) 

[type(x) for x in l] 
[numpy.float64, numpy.float64, numpy.float64, numpy.float64, numpy.float64] 

는 그냥 float에 목록 요소를 변환하지 않습니다 배열 주위에 list를 호출하지만 다른 표현이 원래 np.float 유형을 유지합니다. 두 번째 경우의 부동 소수점 표현들이 실제로 메모리에 표현하는 방법입니다 것을 유의 사항 : 많은 부동 소수점 숫자는 정확한 비트 표현이없는

import decimal 

decimal.Decimal(0.3) 
Decimal('0.299999999999999988897769753748434595763683319091796875') 

때문입니다. 자세한 내용은 사랑하는 정식 Is floating point math broken?을 참조하십시오.

+0

설명해 주셔서 감사합니다. 나는이 문제의 이유를 이해했다. 그러나 numpy 개발자가 예상 된 값을 반환하는 tolist() 함수와 같은 옵션을 지정하지 않은 것은 놀라운 일입니다. – user3015703

+0

@ user3015703 답변이 도움이 될 경우 투표를 잊지 말고 답변을 수락하십시오. 고마워 :) –

+0

이미 설명을 upvoted하지만 난 여전히 문제를 해결하는 방법에 대한 답변을 얻을 찾고 있습니다. 루프의 값을 반올림하는 것 이외의 다른 해결책을 기대해서는 안된다는 말입니까? – user3015703