8000 python large integer conversion to object · Issue #7547 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

python large integer conversion to object #7547

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
2sn opened this issue Apr 14, 2016 · 3 comments
Closed

python large integer conversion to object #7547

2sn opened this issue Apr 14, 2016 · 3 comments

Comments

@2sn
Copy link
Contributor
2sn commented Apr 14, 2016

I was trying to plot something in matplotlib/pylab using

plot((1+np.array([0, 1.e-15]))*1.e27)

which would result in some error message. I use python 3.5.1, numpy 1.11.0, matplotlib 1.5.1

The error arise because somewhere in the matplotlib internals a large integer is added to an array of float64, the result, however is a numpy array of dtype numpy.object with python floats as members

In [1]: np.asarray([1.,2.,3.]) + 1000000000000000000000000000

with output

Out[1]: array([1e+27, 1e+27, 1e+27], dtype=object)

similar for multiplication. I assume this originates from conversion of the scalar to a np.ndarray before the mathematical operation, which seems reasonable at first, but has bad results in the end.

In [2]: np.asarray(1000000000000000000000000000)
Out[2]: array(1000000000000000000000000000, dtype=object)

Wouldn't it be better if the default behaviour for the first case was dtype of np.float64 by default, and if one wanted a non-native (numpy.object) type this has to be specified explicitly, such that

Out[1']: array([  1.00000000e+27,   1.00000000e+27,   1.00000000e+27])

The currently resulting array now (with matplotlib) causes the crash when they try to apply some round operation

In [3]: np.round(Out[1])
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-3-5f7c8426121b> in <module>()
----> 1 np.round(Out[1])

[...]/lib/python3.5/site-packages/numpy/core/fromnumeric.py in round_(a, decimals, out)
   2791     except AttributeError:
   2792         return _wrapit(a, 'round', decimals, out)
-> 2793     return round(decimals, out)
   2794 
   2795 

AttributeError: 'float' object has no attribute 'rint'

The easiest fix at this point would be convert the array to a float array before applying round in round_, changing it to

def round_(a, decimals=0, out=None):
    """
    Round an array to the given number of decimals.

    Refer to `around` for full documentation.

    See Also
    --------
    around : equivalent function

    """python
    try:
        if a.dtype == np.object:
            a = np.array(a, dtype=np.float)
    except AttributeError:
        pass
    try:
        round = a.round
    except AttributeError:
        return _wrapit(a, 'round', decimals, out)
    return round(decimals, out)

It probably should be fixed in matplotlib/ticker class in the first place (matplotlib/matplotlib#6301). Nevertheless, I think the proposed change is a reasonable behaviour for the round_ function instead of giving an error for the case when it is passed an array of python float or integer objects.

@2sn 2sn changed the title python large conversion to object python large integer conversion to object Apr 14, 2016
@charris
Copy link
Member
charris commented Apr 14, 2016

The easy work around on the user side would be to use a big float rather than an integer. On the numpy end, IIRC, we already do a two pass conversion, once for type and a second for value, so this might be a bug in that.

@2sn
Copy link
Contributor Author
2sn commented Apr 14, 2016

Yes, in my post to matplotlib I suggest to convert the integer to numpy.float such that no (very wasteful) numpy array of dtype numpy.object is created unintentionally. Nevertheless, this is something that could occur in other not well-crafted code at times as well, or for beginners, and then the suggested solution would be an easy resolution over getting an error message (though, as you say, really the user code should be fixed in the long run). This behaviour only occurs for large integers that do not fit into int64, so the behaviour changes with size of the python integer, which could be non-obvious in simple tests.

@seberg
Copy link
Member
seberg commented Jan 28, 2024

Going to close it, while the fact that np.array(large_int) returns an object array isn't changed; NEP 50 means that main/NumPy 2.0 shouldn't use that logic in the vast majority cases but return the original dtype of the other operand (convert it to float).

There are more subtleties, and probably some functions which will do the wrong things: Those should be considered bugs to be squared when they come up, this isn't an example for that.

@seberg seberg closed this as completed Jan 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants
0