Numpy: dtype = intの範囲からの予期しない出力

作成日 2020年05月05日  ·  5コメント  ·  ソース: numpy/numpy


[3]の場合:np.arange(-3、0、0.5、dtype = int)
Out [3]:array([-3、-2、-1、0、1、2])

ええと、「1」と「2」を見るのは、両方の数値が0より少し大きいので、私たちにとって少し予想外でした。

通常、これはdtype = intを使用しない結果です。

In [2]: np.arange(-3, 0, 0.5)                                                  
Out[2]: array([-3. , -2.5, -2. , -1.5, -1. , -0.5])
and we should get this with dtype=int:
In [4]: np.arange(-3, 0, 0.5).astype(int)                                      
Out[4]: array([-3, -2, -2, -1, -1,  0])

厄介なマニュアルには次のように記載されています。
dtype:dtype
出力配列のタイプ。 dtypeが指定されていない場合は、他の入力引数からデータ型を推測します。

したがって、出力配列にのみ影響するはずですよね?

import numpy as np
print(np.arange(-3, 0, 0.5))
print(np.arange(-3, 0, 0.5, dtype=int))
print(np.arange(-3, 0, 0.5).astype(int))

エラーメッセージ:

エラーメッセージはありません...

Numpy / Pythonのバージョン情報:

numpyの「1.18.4」(純粋なPython 3.7.6)と「1.18.1」(最新のアップデートが適用されたAnaconda 3.7)でテストしました。 同じ結果。

1.18.4 3.7.6(デフォルト、2020年2月28日、15:25:38)
[Clang 11.0.0( https://github.com/llvm/llvm-project.git eefbff0082c5228e01611f7

1.18.1 3.7.4(デフォルト、2019年8月13日、20:35:49)
[GCC 7.3.0]

00 - Bug numpy.core

最も参考になるコメント

「停止」よりも大きい値を取得することは、実際には良くなく、少し予想外です。 arangeがfloat用でない場合は、float numpyタイプをチェックして、例外を発生させることができます。

また、dtypeの手動入力により、ユーザーは出力のみのastype(dtype)変換のようなものを期待できます。

どうですか:
1.)非整数引数(つまり、開始、停止、ステップ)の例外。
2.)stop> = startかどうかを確認し、そうでない場合は例外を発生させます
3.)関数の先頭で、start、stop、stepをint64にキャストします。
4.)astype(dtype)出力

1.)の代わりに、整数以外の入力が見つかった場合、範囲内のlinspaceにリダイレクトできます。

全てのコメント5件

このようなバグは何度も何度も報告されています。 時間の経過とともに失われた理由から、arangeの実装は次のようなものであるとかなり確信しています。

def arange(start, stop, step, dtype):
    n = (start - stop) // step

    # dtype.type is a cast
    step = dtype.type(start + step) - dtype.type(start)

    # now do what you expect
    return [start + step*i for i in range(n)]

おそらく、その擬似コードをドキュメントに追加する必要がありますか?

ええ、そのコードは正しいです(ただし、 n計算については100%確実ではありません)。 この特定の例はかなり極端で、明らかに壊れています、多分私たちは実際にそれをどうにかして取り除くことができますか?

arangeは、間違いなく壊れた定義を繰り返し嫌っていますが、それに対処するための本当に良い提案は考えられません(おそらく以前に出てきたものかもしれませんが)。
フロートのarange動作をうまく変更できるわけではありません(正確な修正かもしれませんが、エンドポイントの変更は適切なIMOではありません)。 したがって、新しい関数を作成する必要があります...しかし、ほとんどの場合、 linspaceは「正しい」フロート範囲よりも優れているように見えます。修正されたフロート範囲が実際に持っているかどうかはわかりません。ユースケースが多すぎます。

結局、よく考えられた提案が欲しいと思います:/ ...

「停止」よりも大きい値を取得することは、実際には良くなく、少し予想外です。 arangeがfloat用でない場合は、float numpyタイプをチェックして、例外を発生させることができます。

また、dtypeの手動入力により、ユーザーは出力のみのastype(dtype)変換のようなものを期待できます。

どうですか:
1.)非整数引数(つまり、開始、停止、ステップ)の例外。
2.)stop> = startかどうかを確認し、そうでない場合は例外を発生させます
3.)関数の先頭で、start、stop、stepをint64にキャストします。
4.)astype(dtype)出力

1.)の代わりに、整数以外の入力が見つかった場合、範囲内のlinspaceにリダイレクトできます。

ねえ、私はオープンソースの貢献の完全な初心者です。 それを試してみようと思った。 このスニペットはどうですか? @ eric-wieser

x = []
for i in range(start, stop):
    x.append(i)
    x.append(i+step)
print(np.array(x, dtype))

このようなバグは何度も何度も報告されています。 時間の経過とともに失われた理由から、arangeの実装は次のようなものであるとかなり確信しています。

def arange(start, stop, step, dtype):
    n = (start - stop) // step

    # dtype.type is a cast
    step = dtype.type(start + step) - dtype.type(start)

    # now do what you expect
    return [start + step*i for i in range(n)]
このページは役に立ちましたか?
0 / 5 - 0 評価