[Numpy-discussion] Nice float -> integer conversion?

Matthew Brett matthew.brett at gmail.com
Tue Oct 11 17:37:16 EDT 2011


Hi,

On Tue, Oct 11, 2011 at 5:30 PM, Derek Homeier
<derek at astro.physik.uni-goettingen.de> wrote:
> On 11.10.2011, at 9:18PM, josef.pktd at gmail.com wrote:
>>>
>>> In [42]: c = np.zeros(4, np.int16)
>>> In [43]: d = np.zeros(4, np.int32)
>>> In [44]: np.around([1.6,np.nan,np.inf,-np.inf], out=c)
>>> Out[44]: array([2, 0, 0, 0], dtype=int16)
>>>
>>> In [45]: np.around([1.6,np.nan,np.inf,-np.inf], out=d)
>>> Out[45]: array([          2, -2147483648, -2147483648, -2147483648], dtype=int32)
>>>
>>> Perhaps a starting point to harmonise this behaviour and get it closer to
>>> your expectations (it still would not be really nice having to define the
>>> output array first, I guess)...
>>
>> what numpy is this?
>>
> This was 1.6.1
> I did suppress a RuntimeWarning that was raised on the first call, though:
> In [33]: np.around([1.67,np.nan,np.inf,-np.inf], decimals=1, out=d)
> /sw/lib/python2.7/site-packages/numpy/core/fromnumeric.py:37: RuntimeWarning: invalid value encountered in multiply
>  result = getattr(asarray(obj),method)(*args, **kwds)
>
>>>>> np.array([1.6, np.nan, np.inf, -np.inf]).astype(np.int16)
>> array([     1, -32768, -32768, -32768], dtype=int16)
>>>>> np.__version__
>> '1.5.1'
>>>>> a = np.ones(4, np.int16)
>>>>> a[:]=np.array([1.6, np.nan, np.inf, -np.inf])
>>>>> a
>> array([     1, -32768, -32768, -32768], dtype=int16)
>>
>>
>> I thought we get ValueError to avoid nan to zero bugs
>>
>>>>> a[2] = np.nan
>> Traceback (most recent call last):
>>  File "<pyshell#22>", line 1, in <module>
>>    a[2] = np.nan
>> ValueError: cannot convert float NaN to integer
>
> On master, an integer out raises a TypeError for any float input - not sure I'd
> consider that an improvement…
>
>>>> np.__version__
> '2.0.0.dev-8f689df'
>>>> np.around([1.6,-23.42, -13.98, 0.14], out=c)
> Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>  File "/Users/derek/lib/python2.7/site-packages/numpy/core/fromnumeric.py", line 2277, in around
>    return _wrapit(a, 'round', decimals, out)
>  File "/Users/derek/lib/python2.7/site-packages/numpy/core/fromnumeric.py", line 37, in _wrapit
>    result = getattr(asarray(obj),method)(*args, **kwds)
> TypeError: ufunc 'rint' output (typecode 'd') could not be coerced to provided output parameter (typecode 'h') according to the casting rule “same_kind“
>
> I thought the NaN might have been dealt  with first, before casting to int,
> but that doesn't seem to be the case (on master, again):
>
>>>> np.around([1.6,np.nan,np.inf,-np.inf])
> array([  2.,  nan,  inf, -inf])
>>>> np.around([1.6,np.nan,np.inf,-np.inf]).astype(np.int16)
> array([2, 0, 0, 0], dtype=int16)
>>>> np.around([1.6,np.nan,np.inf,-np.inf]).astype(np.int32)
> array([          2, -2147483648, -2147483648, -2147483648], dtype=int32)

Just to whet the appetite:

In [85]: for t in np.sctypes['int'] + np.sctypes['uint']:
   ....:     print np.array([np.nan], float).astype(t)
   ....:
[0]
[0]
[-2147483648]
[-2147483648]
[-9223372036854775808]
[0]
[0]
[2147483648]
[2147483648]
[9223372036854775808]

In [89]: for t in np.sctypes['int'] + np.sctypes['uint']:
   ....:     print np.around(np.array([np.nan], float), out=np.zeros(1, t))
   ....:
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/numpy/core/fromnumeric.py:2278:
RuntimeWarning: invalid value encountered in rint
  return round(decimals, out)
[0]
[0]
[-2147483648]
[-2147483648]
[-9223372036854775808]
[0]
[0]
[2147483648]
[2147483648]
[9223372036854775808]

In [86]: np.__version__
Out[86]: '1.6.1'

Maybe it would be good to have a np.nice_round function?

See you,

Matthew



More information about the NumPy-Discussion mailing list