2017-11-21 8 views
1

私は、python numpyによって生成された間隔の範囲を持っています。値は期待どおりですが、配列がリストに変換されるとき、値は配列と同じではありません。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はこのように動作しますか?リスト内の値を丸めるために別のループを使用せずに、リスト内の値を配列と同じに保つことはできますか?

答えて

4

原因のデータ型と、各タイプの対応__repr__実装のことを起こる:tolistは、その__repr__実装自動的フローティング切り捨てパイソンfloatオブジェクトに各np.floatオブジェクトに変換し、最初のケースで

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

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

ポイント番号はGay algorithmに従います。大藤:

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] 

ただ、配列の周りlistを呼び出すと、floatにリスト要素を変換するが、異なる表現を持つ元のnp.floatタイプを保持していません。

import decimal 

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

多くの浮動小数点数は、正確なビット表現を持っていないので:第2のケースでフロート表現は、彼らが実際にメモリ内でどのように表現されるかであることに注意してください。詳細については、私たちの最愛のカノニカルIs floating point math broken?を参照してください。

+0

ありがとうございます。私はこの問題の理由を理解しました。しかし、numpyの開発者が、tolist()関数のようなオプションを期待値を返すようなものにしなかったのは驚くべきことです。 – user3015703

+0

@ user3015703答えが役に立った場合は、投票を忘れずに回答を受け入れてください。ありがとう:) –

+0

すでに説明をupvotedが、私はまだ問題を解決する方法の答えを得ることを楽しみにしています。つまり、リスト内の値を丸めるためにループを使用する以外の解決策は期待できません。 – user3015703

関連する問題