numpy.array berperilaku aneh dengan / = operator?
Saya mencoba menormalkan larik angka ke kisaran (0, 1] sehingga saya dapat menggunakannya sebagai bobot untuk random.choice () berbobot, jadi saya memasukkan baris ini:
# weights is a nonzero numpy.array
weights /= weights.max()
Namun, Pycharm mengatakan ada parameter yang tidak terisi ke max()fungsi ( Parameter 'initial' unfilled). Saya mencoba ini di REPL dengan operator / = dan dengan divisi "reguler" ( a = a / b) dan mendapatkan hasil yang berbeda untuk keduanya dan kesalahan yang berbeda dari yang diperkirakan Pycharm:
>>> a = numpy.array([1,2,3])
>>> a.max()
3
>>> a /= a.max()
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
a /= a.max()
TypeError: No loop matching the specified signature and casting was found for ufunc true_divide
>>> a = a/a.max()
>>> a
array([0.33333333, 0.66666667, 1. ])
Saya juga menyadari bahwa untuk acak berbobot, bobot harus dijumlahkan menjadi satu daripada dinormalisasi. Tetapi membaginya dengan jumlah menghasilkan hal yang sama persis TypeErrormenggunakan operasi / = (tetapi Pycharm berpikir ini baik-baik saja):
>>> a = numpy.array([1,2,3])
>>> sum(a)
6
>>> a
array([1, 2, 3])
>>> a /= sum(a)
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
a /= sum(a)
TypeError: No loop matching the specified signature and casting was found for ufunc true_divide
>>> a = a / sum(a)
>>> a
array([0.16666667, 0.33333333, 0.5 ])
Apa yang saya temukan di sini? Apakah ini bug aneh di Numpy atau apakah operator / = memiliki kegunaan yang berbeda atau sesuatu? Saya tahu mereka menggunakan __truediv__dan __itruediv__tetapi saya tidak dapat melihat mengapa yang satu memiliki masalah dan yang lainnya tidak. Saya telah mengonfirmasi perilaku ini dengan versi terbaru Numpy dari pip (1.19.2 di Windows x64).
Jawaban
Itu karena numpy peduli pada tipenya. Saat Anda menerapkan pembagian, Anda berubah intmenjadi float. Tapi numpy tidak akan membiarkan Anda melakukan itu! Itulah mengapa nilai-nilai Anda harus sudah ada float. Coba ini:
>>> a = np.array([1.0,2.0,3.0])
>>> a /= sum(a)
>>> a
array([0.16666667, 0.33333333, 0.5 ])
Tetapi mengapa yang lainnya berhasil? Itu karena itu bukan operasi "di tempat". Karenanya lokasi memori baru sedang dibuat. Variabel baru, tipe baru, maka numpy tidak peduli disini.