Skip to content

np.asscalar should pass through scalars #4701

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
mforbes opened this issue May 12, 2014 · 4 comments · Fixed by #12123
Closed

np.asscalar should pass through scalars #4701

mforbes opened this issue May 12, 2014 · 4 comments · Fixed by #12123

Comments

@mforbes
Copy link
Contributor

mforbes commented May 12, 2014

Suggestion
It would be very convenient if np.asscalar() would pass through scalars. The use-case is to ensure that an argument is a scalar, regardless what is passed in (as long as it behaves as a scalar).

>>> np.asarray(1.0)
1.0
>>> np.asarray(1j)
1j

Presently these fail as the implementation simply looks for the .item() method, which scalars do not possess:

>>> np.asarray(1.0)
AttributeError                            Traceback (most recent call last)
<ipython-input-13-c6bc08be135e> in <module>()
----> 1 np.asscalar(1.0)

.../python2.7/site-packages/numpy/lib/type_check.pyc in asscalar(a)
    461 
    462     """
--> 463     return a.item()
    464 
    465 #-----------------------------------------------------------------------------

AttributeError: 'float' object has no attribute 'item'```

Rational
It is common to use np.asarray() to ensure that the argument is an array (in the case that it might be a list etc.). In an analogous use case, it would be useful to be able to use np.asscalar() to ensure that an argument is a scalar (as long as it can be converted to a scalar).

Workaround
Convert the argument to an array first.

np.asscalar(np.asarray(x))

Resolution
Perhaps code like the following would work:

def asscalar(a):
    try:
        return a.item()
    except AttributeError, e:
        return np.asarray(a).item()
liufei11111 added a commit to liufei11111/numpy that referenced this issue Nov 7, 2014
…rameters passed in to np.where() is evaluated first before going into the function however, the denominator can be zero at that time. I allocated the intermediate result based on different formulas for rate == 0.0 and not equal to and fixes numpy#5046. Also, a easy fix for asocial doesn’t take integer because it assumes passing in an np.array. I convert everything to np.array first and then retrieve the item. Fixed numpy#4701
@dpdoughe
Copy link

I'd like to reopen this issue. This is not fixed in numpy 1.13. It doesn't have the fix mentioned here

In [4]: np.asscalar(3.4)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-8460cfbb0c19> in <module>()
----> 1 np.asscalar(3.4)

/home/foo/.virtualenv/myapp/lib/python2.7/site-packages/numpy/lib/type_check.pyc in asscalar(a)
    478 
    479     """
--> 480     return a.item()
    481 
    482 #-----------------------------------------------------------------------------

AttributeError: 'float' object has no attribute 'item'
def asscalar(a):
    """
    Convert an array of size 1 to its scalar equivalent.

    Parameters
    ----------
    a : ndarray
        Input array of size 1.

    Returns
    -------
    out : scalar
        Scalar representation of `a`. The output data type is the same type
       returned by the input's `item` method.

    Examples
    --------
    >>> np.asscalar(np.array([24]))
    24

    """
    return a.item()

@eric-wieser eric-wieser reopened this Dec 22, 2017
@eric-wieser
Copy link
Member

Looks like the wrong issue number was used in the commit that closed this

seawolf631 added a commit to seawolf631/numpy that referenced this issue Dec 23, 2017
SpoorthyBhat added a commit to SpoorthyBhat/numpy that referenced this issue Mar 1, 2018
Allows np.scalar to pass through scalars
SpoorthyBhat added a commit to SpoorthyBhat/numpy that referenced this issue Mar 1, 2018
Allows numpy.asscalar to pass scalars
SpoorthyBhat added a commit to SpoorthyBhat/numpy that referenced this issue Mar 1, 2018
BUG: fixes numpy#4701 related to numpy.asscalar
SpoorthyBhat added a commit to SpoorthyBhat/numpy that referenced this issue Mar 4, 2018
@eric-wieser
Copy link
Member

eric-wieser commented Sep 5, 2018

We need to make a decision on this before we get even more PRs attempting to "fix" it. To date:

Un-tagging as easy to stop us getting more of these

@eric-wieser
Copy link
Member

eric-wieser commented Sep 5, 2018

One of the main problems I have with asscalar is that it's just not consistent with isscalar - isscalar(x) currently does not imply asscalar(x) is x:

>>> x = np.float64
>>> isscalar(x)
True
>>> type(x)
<class 'numpy.float64'>
>>> type(asscalar(x))
<class 'float'>

Overall, we have three conflicting definitions of scalar:

  1. Is a python scalar - the type of object returned from asscalar
  2. Is a python or numpy scalar - objects meeting isscalar
  3. is a 0d array - np.ndim(x) == 0

Almost every time I see an internal use of isscalar, the intention was actually np.ndim(x) == 0. The exceptions are places that decide whether *= will modify in-place

gvgramazio added a commit to gvgramazio/trpo that referenced this issue Nov 5, 2018
As explained in detail in a [numpy issue](numpy/numpy#4701), `np.asscalar` doesn't pass through scalars. This is because it looks for `item()` method that `int` and `float` don't have. A possible workaround suggest there is the one I proposed to you. In this way your script doesn't fail with other environments such as `LunarLanderContinuous-v2`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants