I have a function which can accept either a list or a numpy array.
In either case, the list/array has a single element (always). I just need to return a float.
So, e.g., I could receive:
list_ = [4]
or the numpy array:
array_ = array([4])
And I should return
4.0
So, naturally (I would say), I employ float(...) on list_ and get:
TypeError: float() argument must be a string or a number
I do the same to array_ and this time it works by responding with "4.0". From this, I learn that Python's list cannot be converted to float this way.
Based on the success with the numpy array conversion to float this lead me to the approach:
float(np.asarray(list_))
And this works when list_ is both a Python list and when it is a numpy array.
Question
But it seems like this approach has an overhead first converting the list to a numpy array and then to float. Basically: Is there a better way of doing this?
Just access the first item of the list/array, using the index access and the index 0:
>>> list_ = [4]
>>> list_[0]
4
>>> array_ = np.array([4])
>>> array_[0]
4
This will be an int
since that was what you inserted in the first place. If you need it to be a float for some reason, you can call float()
on it then:
>>> float(list_[0])
4.0
You may want to use the ndarray.item
method, as in a.item()
. This is also equivalent to np.asscalar(a)
. This has the benefit of working in situations with views and superfluous axes, while the above solutions will currently break. For example,
>>> a = np.asarray(1).view()
>>> a.item() # correct
1
>>> a[0] # breaks
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: too many indices for array
>>> a = np.asarray([[2]])
>>> a.item() # correct
2
>>> a[0] # bad result
array([2])
This also has the benefit of throwing an exception if the array is not a singleton, while the a[0]
approach will silently proceed (which may lead to bugs sneaking through undetected).
>>> a = np.asarray([1, 2])
>>> a[0] # silently proceeds
1
>>> a.item() # detects incorrect size
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: can only convert an array of size 1 to a Python scalar
Use numpy.asscalar to convert a numpy array / matrix a scalar value:
>>> a=numpy.array([[[[42]]]])
>>> numpy.asscalar(a)
42
The output data type is the same type returned by the input’s item
method.
It has built in error-checking if there is more than an single element:
>>> a=numpy.array([1, 2])
>>> numpy.asscalar(a)
gives:
ValueError: can only convert an array of size 1 to a Python scalar
Note: the object passed to asscalar
must respond to item
, so passing a list or tuple won't work.
I would simply use,
np.asarray(input, dtype=np.float)[0]
- If
input
is an ndarray
of the right dtype, there is no overhead, since np.asarray
does nothing in this case.
- if
input
is a list
, np.asarray
makes sure the output is of the right type.