Mengapa daftar kosong [] sedang disimpulkan sebagai tipe float saat menggunakan np.append?

np.append([1,2,3], [0])
# output: array([1, 2, 3, 0]), dtype = np.int64

np.append([1,2,3], [])
# output: array([1., 2., 3.]), dtype = np.float64

Ini persisten bahkan ketika menggunakan np.array([1,2,3], dtype=np.int32) AS arr.

Tidak mungkin menentukan dtype untuk ditambahkan, jadi saya hanya ingin tahu mengapa ini terjadi. Compatenate numpy melakukan hal yang sama, tetapi ketika saya mencoba menentukan DTYPE saya mendapatkan kesalahan:

np.concatenate([[1,2,3], []], dtype=np.int64)

Kesalahan:

TypeError: Cannot cast array data from dtype('float64') to dtype('int64') according to the rule 'same_kind'

Tetapi akhirnya jika saya mengatur aturan pengecoran yang tidak aman itu berfungsi:

np.concatenate([[1,2,3], []], dtype=np.int64, casting='unsafe')

Mengapa [] dianggap float?

6
Kevin 29 Mei 2021, 01:14

2 jawaban

Jawaban Terbaik

np.append tunduk pada aturan semantik yang didefinisikan dengan baik seperti operasi biner numpy. Akibatnya, pertama-tama mengkonversi operan input ke array numpy jika ini tidak terjadi (biasanya dengan np.array) dan kemudian menerapkan aturan semantik untuk menemukan jenis array yang dihasilkan dan memeriksa itu adalah operasi yang valid sebelumnya menerapkan operasi aktual (di sini gabungan). Tipe array dikembalikan oleh np.array numpy.float64 sebagaimana tercantum dalam dokumentasi np.empty. Ini pilihan sewenang-wenang dilakukan sejak lama dan belum diubah karena tidak untuk memecahkan kode lama. Harap dicatat bahwa sepertinya tidak semua pengembang numby setuju dengan pilihan saat ini dan ini adalah masalah perdebatan. Untuk informasi lebih lanjut, Anda dapat membaca ini membuka masalah ini.

Aturan praktis adalah dengan menggunakan array numpy yang ada atau untuk melakukan konversi eksplisit ke array numpy menggunakan np.array dengan parameter tetap dtype (seperti yang dijelaskan dalam komentar di atas).

4
Jérôme Richard 28 Mei 2021, 23:03

Lihat kode untuk np.append (via docs link atau ipython):

def append(arr, values, axis=None):
    arr = asanyarray(arr)
    if axis is None:
        if arr.ndim != 1:
            arr = arr.ravel()
        values = ravel(values)
        axis = arr.ndim-1
    return concatenate((arr, values), axis=axis)

Argumen pertama berubah menjadi array, jika sudah tidak.

Anda tidak menentukan sumbu, jadi keduanya arr dan values dirampok - berubah menjadi array 1D. np.ravel juga kode python, dan apakah asanyarray(a).ravel(order=order)

Jadi inferensi DTYPE dilakukan dengan np.asanyarray.

Sisa tindakannya adalah np.concatenate. Ini juga akan mengubah input ke array jika perlu. Hasil DTYPE adalah "tertinggi" dari input.

np.append adalah cara alternatif (IMO) yang disusun dengan buruk menggunakan np.concatenate. Ini bukan daftar tambahkan klon.

Juga berhati-hati tentang array "kosong":

In [73]: np.array([])
Out[73]: array([], dtype=float64)
In [74]: np.empty((0))
Out[74]: array([], dtype=float64)
In [75]: np.empty((0),int)
Out[75]: array([], dtype=int64)

Idiom daftar umum

alist = []
for i in range(10):
    alist.append(i)

Tidak menerjemahkan dengan baik ke numpy. Bangun daftar array, dan lakukan satu concatenate/vstack pada akhirnya. Jangan beralih dari array "kosong", namun dibuat.

1
hpaulj 28 Mei 2021, 23:24