Hello,

Currently, the built-in Python round (which is different from np.round) when 
called on a np.float64 returns a np.float64, due to its __round__ method. A 
congruous statement is true for np.float32. However, since Python 3, the 
default behavior of round is to return a Python int when it operates on a 
Python float. This is a mismatch according to the Liskov Substitution 
Principle<https://en.wikipedia.org/wiki/Liskov_substitution_principle>, as both 
these types subclass Python’s float. This has been brought up in 
gh-15297<https://github.com/numpy/numpy/issues/15297>. Here is the problem 
summed up in code:

>>> type(round(np.float64(5)))
<class 'numpy.float64'>
>>> type(round(np.float32(5)))
<class 'numpy.float32'>
>>> type(round(float(5)))
<class 'int'>

This problem manifests itself most prominently when trying to index into 
collections:

>>> np.arange(6)[round(float(5))]
5
>>> np.arange(6)[round(np.float64(5))]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis 
(`None`) and integer or boolean arrays are valid indices

There still remains the question, do we return Python ints or np.int64s?

  *   Python ints have the advantage of not overflowing.
  *   If we decide to add __round__ to arrays in the future, Python ints may 
become inconsistent with our design, as such a method will return an int64 
array.

This was issue was discussed in the weekly triage meeting today, and the 
following plan of action was proposed:

  *   change scalar floats to return integers for __round__ (which integer type 
was not discussed, I propose np.int64)
  *   not change anything else: not 0d arrays and not other numpy functionality
Does anyone have any thoughts on the proposal?
Best regards,
Hameer Abbasi
_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@python.org
https://mail.python.org/mailman/listinfo/numpy-discussion

Reply via email to