Convert list or numpy array of single element to f

2020-02-09 06:12发布

问题:

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?

回答1:

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


回答2:

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


回答3:

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.



回答4:

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.