numpy.array'in / = operatörüyle tuhaf davranışları var mı?

Sep 11 2020

Bir sayı dizisini (0, 1] aralığına normalleştirmeye çalışıyorum, böylece onları ağırlıklı random.choice () için ağırlık olarak kullanabilirim, bu yüzden şu satırı girdim:

# weights is a nonzero numpy.array
weights /= weights.max()

Ancak Pycharm, max()( Parameter 'initial' unfilled) işlevinde doldurulmamış bir parametre olduğunu söyledi . Bunu REPL'de / = operatörü ve "normal" bölme ( a = a / b) ile denedim ve her ikisi için farklı sonuçlar ve Pycharm'ın düşündüğünden farklı bir hata aldım:

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

Ben de ağırlıklı rastgele için, ağırlıklar için gerekli fark Özetle birine ziyade kendisine normalize edilmesi. Ancak bunu toplama bölmek TypeError/ = işlemini kullanarak aynı sonucu verdi (ancak Pycharm bunun uygun olduğunu düşündü):

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

Burada neyle karşılaştım? Bu Numpy'deki tuhaf bir hata mı yoksa / = operatörünün farklı bir kullanımı mı var? Ben kullandıkları biliyorum __truediv__ve __itruediv__ancak bir sorun vardır ve diğer desteklemez neden göremiyorum. Bu davranışı pip'ten Numpy'nin en son sürümüyle (Windows x64'te 1.19.2) onayladım.

Yanıtlar

1 Fahim Sep 11 2020 at 23:24

Çünkü numpy türü önemsiyor. Eğer bölünme uyguladığınızda, değiştiriyorsun intiçin float. Ama numpy bunu yapmana izin vermeyecek! Bu yüzden değerleriniz zaten içinde olmalıdır float. Bunu dene:

>>> a = np.array([1.0,2.0,3.0])
>>> a /= sum(a)
>>> a
array([0.16666667, 0.33333333, 0.5       ])

Peki diğeri neden işe yaradı? Çünkü bu "yerinde" bir işlem değil. Dolayısıyla yeni bir hafıza konumu yaratılıyor. Yeni değişken, yeni tip, bu yüzden numpy burada umursamıyor.