Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can numpy.rint to return an Int32?

I'm doing

ret = np.rint(y * 4)
return ret

And I want it to return Int32. I tried adding dtype='Int32', but it errors saying: TypeError: No loop matching the specified signature and casting was found for ufunc rint

I apologize if this is a basic question, but I tried to search for an answer to no avail

like image 855
Shamoon Avatar asked Jan 27 '23 14:01

Shamoon


2 Answers

ufuncs have specific rules of what kinds of output they produce given the input. For rint the rules are:

In [41]: np.rint.types                                                          
Out[41]: ['e->e', 'f->f', 'd->d', 'g->g', 'F->F', 'D->D', 'G->G', 'O->O']

On top of that there are rules about what dtypes can be cast to other dtypes. We can play with the out and the casting parameters to produce an integer output, but simply using astype after is simpler.

So rint normally returns a matching float, even though the values are rounded.

In [43]: np.rint(np.linspace(0,10,8))                                           
Out[43]: array([ 0.,  1.,  3.,  4.,  6.,  7.,  9., 10.])

Simply providing an int out doesn't work:

In [44]: np.rint(np.linspace(0,10,8),out=np.zeros(8,int))                       
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-44-e7f13fa29434> in <module>
----> 1 np.rint(np.linspace(0,10,8),out=np.zeros(8,int))

TypeError: ufunc 'rint' output (typecode 'd') could not be coerced to provided output parameter (typecode 'l') according to the casting rule ''same_kind''

We have to give it permission to do a float to int casting:

In [45]: np.rint(np.linspace(0,10,8),out=np.zeros(8,int),casting='unsafe')      
Out[45]: array([ 0,  1,  3,  4,  6,  7,  9, 10])

The default casting for astype is 'unsafe'.

In [55]: np.rint(np.linspace(0,10,8)).astype(int,casting='safe')                
TypeError: Cannot cast array from dtype('float64') to dtype('int64') according to the rule 'safe'
like image 172
hpaulj Avatar answered Jan 30 '23 08:01

hpaulj


You can use the astype method (docs here)

ret = np.rint(y * 4).astype(np.int32)

Note that astype creates a copy, so it may be not the most efficient memory operation (most times you wont care).

sidenote: Why rint outputs a float dtype array of integers is beyond me.

like image 27
Tarifazo Avatar answered Jan 30 '23 07:01

Tarifazo