Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

numpy array casting ruled not 'safe'

Indexing one numpy array with another - both are defined as dtype='uint32'. Using numpy.take to index and get an unsafe casting error. Not come across this before. Any idea what is going on?

Python 2.7.8 |Anaconda 2.1.0 (32-bit)| (default, Jul  2 2014, 15:13:35) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.

>>> import numpy
>>> numpy.__version__
'1.9.0'

>>> a = numpy.array([9, 7, 5, 4, 3, 1], dtype=numpy.uint32)
>>> b = numpy.array([1, 3], dtype=numpy.uint32)
>>> c = a.take(b)

Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    c = a.take(b)
TypeError: Cannot cast array data from dtype('uint32') to dtype('int32') according to the rule 'safe'
like image 654
Henry Thornton Avatar asked Mar 04 '15 11:03

Henry Thornton


1 Answers

This is quite common when working NumPy functions that require indexes or lengths to be specified (it's not just take, see for example here).

The problem is that, for indexing purposes, NumPy would like to treat your uint32 array as an int32 array (which is probably the "pointer" integer type on your 32 bit system, np.intp) and wants to cast it down to that type.

It can't do this safely - some of the integers in an unsigned array might not be representable as a signed 32 bit integer. The error you see reflects this.

This means that you'll get the same error if b has dtype int64 or a float dtype, but not if it is int32 or a smaller integer dtype.

For what it's worth, this isn't an immediate problem for the indexing notation a[b] which allows the unsafe casting (but will raise an error if the index is out of bounds). Try for example a[2**31] - NumPy casts to int32 but then complains that the index -2147483648 is out of bounds.

like image 63
Alex Riley Avatar answered Oct 15 '22 06:10

Alex Riley