Numpy: Keluaran tak terduga dari arange dengan dtype = int

Dibuat pada 5 Mei 2020  ·  5Komentar  ·  Sumber: numpy/numpy


Dalam [3]: np.arange (-3, 0, 0.5, dtype = int)
Keluar [3]: larik ([- 3, -2, -1, 0, 1, 2])

Nah, melihat angka "1" dan "2" agak tidak terduga bagi kami karena kedua angka tersebut sedikit lebih besar dari 0.

Biasanya, ini adalah hasil tanpa 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])

Manual numpy menyatakan:
dtype: dtype
Jenis larik keluaran. Jika dtype tidak diberikan, simpulkan tipe data dari argumen input lainnya.

Jadi seharusnya hanya mempengaruhi larik keluaran, bukan?

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))

Pesan eror:

Tidak ada pesan kesalahan ...

Informasi versi Numpy / Python:

Kami mengujinya di bawah numpy '1.18.4' (Python 3.7.6 murni) serta '1.18.1' (Anaconda 3.7 dengan pembaruan terbaru diterapkan). Hasil yang sama.

1.18.4 3.7.6 (default, 28 Feb 2020, 15:25:38)
[Dentang 11.0.0 ( https://github.com/llvm/llvm-project.git eefbff0082c5228e01611f7

1.18.1 3.7.4 (default, 13 Agustus 2019, 20:35:49)
[GCC 7.3.0]

00 - Bug numpy.core

Komentar yang paling membantu

Mendapatkan nilai yang lebih besar dari "berhenti" sebenarnya tidak baik dan sedikit tidak terduga. Jika arange bukan untuk float, Anda bisa memeriksa jenis floaty numpy dan memunculkan pengecualian.

Juga entri manual untuk dtype benar-benar memungkinkan pengguna mengharapkan sesuatu seperti konversi astype (dtype) hanya dari output.

Bagaimana tentang:
1.) Pengecualian untuk argumen non-integer (yaitu mulai, berhenti, langkah).
2.) Periksa apakah berhenti> = mulai, jika tidak, buat pengecualian
3.) Cast start, stop, step to int64 di awal fungsi.
4.) astype (dtype) outputnya

Alih-alih 1.) Anda dapat mengalihkan ke linspace di dalam arange jika masukan non-integer ditemukan.

Semua 5 komentar

Bug seperti ini dilaporkan berulang kali. Untuk alasan waktu yang hilang, saya cukup yakin penerapan arange adalah seperti:

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

Mungkin kita harus menambahkan pseudo-code itu ke dokumentasi?

Ya, kode itu benar (meskipun tidak 100% yakin tentang perhitungan n ). Contoh spesifik ini cukup ekstrim, dan jelas rusak, mungkin kita bisa benar-benar menghilangkannya?

arange berulang kali dibenci karena definisi yang bisa dibilang rusak, tetapi saya tidak dapat memikirkan proposal yang benar-benar bagus untuk mengatasinya (meskipun mungkin ada yang muncul sebelumnya).
Ini tidak seperti kita dapat mengubah perilaku arange untuk float dengan baik (mungkin perbaikan presisi, tetapi perubahan titik akhir bukanlah IMO yang baik). Jadi kita perlu membuat fungsi baru ... Tetapi dalam banyak kasus, menurut saya linspace lebih baik daripada float arange yang "benar", saya tidak yakin bahwa float-arange yang dikoreksi benar-benar memiliki terlalu banyak kasus penggunaan.

Pada akhirnya, saya rasa saya ingin proposal yang dipikirkan dengan matang: / ...

Mendapatkan nilai yang lebih besar dari "berhenti" sebenarnya tidak baik dan sedikit tidak terduga. Jika arange bukan untuk float, Anda bisa memeriksa jenis floaty numpy dan memunculkan pengecualian.

Juga entri manual untuk dtype benar-benar memungkinkan pengguna mengharapkan sesuatu seperti konversi astype (dtype) hanya dari output.

Bagaimana tentang:
1.) Pengecualian untuk argumen non-integer (yaitu mulai, berhenti, langkah).
2.) Periksa apakah berhenti> = mulai, jika tidak, buat pengecualian
3.) Cast start, stop, step to int64 di awal fungsi.
4.) astype (dtype) outputnya

Alih-alih 1.) Anda dapat mengalihkan ke linspace di dalam arange jika masukan non-integer ditemukan.

Hai, saya benar-benar pemula dalam kontribusi open source. Berpikir untuk mencobanya. Bagaimana dengan potongan ini? @ eric-wieser

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

Bug seperti ini dilaporkan berulang kali. Untuk alasan waktu yang hilang, saya cukup yakin penerapan arange adalah seperti:

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)]
Apakah halaman ini membantu?
0 / 5 - 0 peringkat