質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • Python 3.x

    5320questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • NumPy

    376questions

    NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

python3.6.0のnumpyでの実行結果がおかしいです

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 140

114514

score 1

python3.6.0で以下のコードを入力したところ

import numpy as np
a=np.arange(0.5,0.8,0.01)
a

実行結果が

array([ 0.5 ,  0.51,  0.52,  0.53,  0.54,  0.55,  0.56,  0.57,  0.58,
0.59,  0.6 ,  0.61,  0.62,  0.63,  0.64,  0.65,  0.66,  0.67,
0.68,  0.69,  0.7 ,  0.71,  0.72,  0.73,  0.74,  0.75,  0.76,
0.77,  0.78,  0.79,  0.8 ])

となりました。

正しい実行結果は
array([ 0.5 ,  0.51,  0.52,  0.53,  0.54,  0.55,  0.56,  0.57,  0.58,
0.59,  0.6 ,  0.61,  0.62,  0.63,  0.64,  0.65,  0.66,  0.67,
0.68,  0.69,  0.7 ,  0.71,  0.72,  0.73,  0.74,  0.75,  0.76,
0.77,  0.78,  0.79])
だと思うのですが、これはバグでしょうか?

値の範囲を変えて確かめようと思い、以下のように入力すると
np.arange(0.4,0.7,0.01)

実行結果は
array([ 0.4 ,  0.41,  0.42,  0.43,  0.44,  0.45,  0.46,  0.47,  0.48,
0.49,  0.5 ,  0.51,  0.52,  0.53,  0.54,  0.55,  0.56,  0.57,
0.58,  0.59,  0.6 ,  0.61,  0.62,  0.63,  0.64,  0.65,  0.66,
0.67,  0.68,  0.69])
と正しい結果はでます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kawakawa2018

    2018/04/27 01:55

    いい質問ありがとうございます。これは重要ですね。pandasの基本はデータ配列をきちんと作るところから始まりますから。

    キャンセル

回答 2

+3

追記:自分の回答はずいぶん迂遠であり、もっと単純に回答できていたほうがよかったです(反省)。

mkgreiさんがリンクしてくださっているcan110さん回答で充分であり、多少追加するにしても以下ぐらいがよかったと思いました。

「arangeは閉空間[start, stop)を計算するので、要素数を決める演算で浮動小数点数の演算誤差の影響を受ける。期待通りの要素数にならないケースがあるのはリファレンスにあるとおり。本件でいえば
math.ceil((0.8-0.5)/0.01)が31になるためこのような結果になる」

白状しますとmath.floor((0.8-0.5)/0.01)で求めてるというハヤトチリのため「なんか誤差があると思うしリファレンスにもそう書いてある」みたいな漠然なコメントをしてしまったのです。お恥ずかしい限りです。math.ceilであるべきだと気づくことができれば最初から単純明快に回答できてたと思います。

元の回答

ちょっとやってみますと

import numpy as np

def zoo():
  for f in ['0.', '0.0', '0.00', '0.000', '0.0000']:
    b, e, s = [*map(float, f'{f}5 {f}8 {f}01'.split(' '))]
    a = np.arange(b, e, s).shape
    print(f'{b}, {e}, {s} : {a}')


===>

0.5, 0.8, 0.01 : (31,)
0.05, 0.08, 0.001 : (30,)
0.005, 0.008, 0.0001 : (30,)
0.0005, 0.0008, 1e-05 : (30,)
5e-05, 8e-05, 1e-06 : (31,)


ごらんのとおりいつも都合よく30要素にはなってないように見えます。なにせ浮動小数点数を指定してますので、「必ず30要素じゃないとバグ」と自分には思えません。


なんて遠回りをしたあとで「あ・・・リファレンスみなきゃ」と思い見てみると

When using a non-integer step, such as 0.1, the results will often not be consistent. It is better to use linspace for these cases.

ちゃんと書いてあるみたいです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/27 01:55

    予想以上に速い回答で驚いてます。
    リファレンスも示していただきありがとうございます。

    気になったのですが、
    浮動小数点数だと必ずしも30要素にならない理由は、
    例えば、
    a=np.arange(0.5,0.8,0.01)
    と入力した際に「0.8」が「0.801」というように0.8より大きい数と認識される
    という解釈であってますでしょうか?

    キャンセル

  • 2018/04/27 04:05 編集

    ですね。
    f'{0.8:.20f} {0.01:.20f}'
    =>'0.80000000000000004441 0.01000000000000000021'
    みたいにするとわかります。
    ---追記---
    ですねと書きましたが、そう単純ではないです。0.8が文字通りの値ではないというのはおっしゃるとおりですが、0.01もそうですし、それらの値を計算した結果など全て誤差があります。その誤差がどう蓄積するかが問題です。本件の場合は
    0.8 - a[-1]が負の値になるのでいかにもバグに見えますが計算の都合でそういうおかしなことにもなり得ると解釈しました。
    not be consistent.
    と言われるとほぼなんでも許容しないといけなさそうですので。

    キャンセル

  • 2018/04/27 06:56 編集

    この質問を見て気になったので、両方の最後の要素を30桁出してみたら、
    0.800000000000000266453525910038
    0.690000000000000279776202205539
    別段違いはなさそうですが・・・
    それはそうとして、
    >>> c = 0.5
    >>> for _ in range(31):
    ... print("{:.30f}".format(c))
    ... c += 0.01
    これで最後に出力される数字は上と同じだった(ちょっと意外でした)
    そして、
    >>> (0.7-0.4)/0.01
    29.999999999999993
    >>> (0.8-0.5)/0.01
    30.000000000000004
    >>> int((0.7-0.4)/0.01)
    29
    >>> int((0.8-0.5)/0.01)
    30
    だから、そういう実装なんだな、と勝手に思いました(要素数=ループ回数の決まり方が)

    キャンセル

  • 2018/04/27 07:40

    hayataka2049さんがおっしゃるとおりと思います。arangeの機能は閉空間

    [start, stop)

    を計算することなので、要素数を求めるにはmath.ceil((stop-start)/step)とやりますよね?浮動小数点数の演算誤差のため期待が30でも計算結果が30より少しだけ大きな値になってしまう以上は31要素とarangeが判断したのはしかたないことだと思います。

    下記のソースのPyArray_Arangeという関数の実装をみると実際に上のように要素数を求めてるように見えました。

    https://github.com/numpy/numpy/blob/a04676a2d1048dc1cc62255547f63c7a17000d02/numpy/core/src/multiarray/ctors.c

    キャンセル

  • 2018/04/27 10:13

    要素数の計算をする際は小数点切り上げをすると分かり大変参考になりました。
    色々調べてくださり大変感謝しております。

    キャンセル

checkベストアンサー

+2

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/27 09:29 編集

    リンクを貼ってくださりありがとうございます。

    要素数を30にするためには
    np.arange(5,8)/100
    とすれば安定することが分かり参考になりました。

    キャンセル

  • 2018/04/27 12:27

    どちらかといえばlinspaceが明解であるように思います。
    区間数がNでもN+1でもどっちでも構わない場合(散布図などのグラフの軸生成)や区間が整数の場合ならarange, 区間が実数で厳密にN個としたい(FFTの周波数や棒グラフのラベルなどの軸を生成)ならlinspaceがいいんじゃないでしょうか。

    キャンセル

  • 2018/04/27 22:22

    確かにlinspaceだと最後の値を確実に含むので、小数点を含む場合はそちらの方が分かりやすいですね。
    ここまで色々な情報を教えてくださると思っていなかったので、本当に感謝しております。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 受付中

    パーセンタイルについて

    そもそもパーセンタイルとはどういったものでしょうか?   - サンプル込みで回答頂けると幸いです。

  • 解決済

    python listについて

    いま人のコードを読んでいるのですが、以下のことわかる方いたらお力添えお願いいたします。 mean(times[:,i1:i2],1) こちらの解釈はtimes[:,i1

  • 受付中

    配列に関する「短い記述」が、何を示しているのかわからない。

    はじめまして。 現在以下の記事を参考にしながら、深層学習やPythonについて学んでいる者です。 http://qiita.com/kiminaka/items/9ae1957

  • 解決済

    listからnumpy.ndarrayへの変換方法

    [[0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0],

  • 受付中

    関数の実装、matmulを利用

    追記:print(np.matmul(A, x)) まではできたのですが、それ以降はどのように書けば良いでしょうか?

  • 解決済

    dotとmultiplyの違い

    Cosine類似度をnumpyで表現したいです。 正解が以下のコードだそうです。 norm = np.linalg.norm(train_X, ord=2, a

  • 解決済

    numpyを使ってscipyを使う理由

    numpyを使ってかつscipyを使う理由がわかりません。 よく、 import scipy import numpy as np とコードの上に書かれているものを見ま

  • 解決済

    numpyのdeleteについて

    numpy配列を範囲指定して削除したいのですが方法がわからず困っています。 numpy.delete(arr, obj, axis=0) 以上のコマンドを使って、ある範

同じタグがついた質問を見る

  • Python 3.x

    5320questions

    Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

  • NumPy

    376questions

    NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。