2

I always use from __future__ import division to avoid integer division problems. I just came across a case where it apparently still persists:

np.array([10])**(-1)

returns array([0]), contrary to 1/np.array([10]), which returns array([ 0.1]) as expected.

I know this can be fixed, e.g. by using np.array([10])**(-1.) or converting the array to floats using astype('float'). I would just like to know why it behaves like this, since it seems slightly inconsistent to me given that e.g. 10**(-1) gives 0.1.

Alex Riley
  • 169,130
  • 45
  • 262
  • 238
jacob
  • 869
  • 2
  • 10
  • 23

2 Answers2

3

numpy.array() uses operator overloading to implement features. ** is handled by the object.__pow__() special method, for example.

The / operator is normally handled by object.__div__ (and the __rdiv__ method for right-hand-side values), and the from __future__ import division 'switch' causes Python to use the object.__truediv__ method instead.

However, the ** operator is not influenced by the switch; Python will continue to call object.__pow__ and numpy won't know you used the __future__ import.

As such, it'll continue to return integer results when you give it integer operands; it will not coerce to float even then.

Note that Python offers a floor division operator too, in the form of the // operator and the __floordiv__ hook. There is no such flooring equivalent for exponentiation, so numpy has no other options to offer you a distinction between using float and int operands.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Ok that makes sense. Maybe the more confusing thing to me is then that 10**(-1) always seems to use float division, even without the "from future import division" – jacob Feb 20 '15 at 10:29
  • @jacob: see the [`**` power operator documentation](https://docs.python.org/2/reference/expressions.html#the-power-operator); in Python using an integer exponent *used* to raise an exception instead. It was deemed more helpful to coerce to float instead in those cases. I guess that Numpy made a different choice here as their use-cases are different (different programmer audience). – Martijn Pieters Feb 20 '15 at 10:36
2

As a footnote to the answer given above, you can check what NumPy will return for particular input array types by inspecting the types attribute of the appropriate universal function.

For NumPy arrays, the power operator ** corresponds to np.power:

>>> np.power.types
['bb->b', 'BB->B', 'hh->h', 'HH->H', 'ii->i', 'II->I', 'll->l', 'LL->L', 'qq->q', 
 'QQ->Q', 'ee->e', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G', 'OO->O']

Python-compatible integer types are denoted by l, Python-compatible floats by d (see here).

You can see that for two integer types, ** will return another integer: 'll->l'

For NumPy arrays, the division operator / corresponds to np.divide:

>>> np.divide.types
['bb->d', 'BB->d', 'hh->d', 'HH->d', 'ii->d', 'II->d', 'll->d', 'LL->d', 'qq->d', 
 'QQ->d', 'ee->e', 'ff->f', 'dd->d', 'gg->g', 'FF->F', 'DD->D', 'GG->G', 'mq->m', 
 'md->m', 'mm->d', 'OO->O']

Here, given two integer types (and for most other inputs), a float will be returned: 'll->d'

Alex Riley
  • 169,130
  • 45
  • 262
  • 238