I have an array that contains strings representing numbers.
a = ["101", "102", "103"]
I wanted to take the average of this array, so I tried mapping each element into a float
and then using np.average
>>> np.average(map(float, a))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<__array_function__ internals>", line 5, in average
File "C:\Users\alonso\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\lib\function_base.py", line 380, in average
avg = a.mean(axis)
File "C:\Users\alonso\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\core\_methods.py", line 190, in _mean
ret = ret / rcount
TypeError: unsupported operand type(s) for /: 'map' and 'int'
If I convert the numbers by iteration it works, but if I have to use iteration this defeats the purpose of map.
np.average([float(i) for i in a])
102.0
Map returns a map object
map(float, a)
<map object at 0x0000022E46035D60>
But then, it looks like python doesn't know how to divide map by int.
If I convert map into a list, then it works, it doesn't create a list of maps, but rather evaluates the map value and creates a list of floats
list(map(float, a))
[101.0, 102.0, 103.0]
However converting map into an array doesn't.
np.array(map(float, a))
array(<map object at 0x0000022E2D4A84F0>, dtype=object)
np.average(np.array(map(float, a)))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<__array_function__ internals>", line 5, in average
File "C:\Users\alonso\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\lib\function_base.py", line 380, in average
avg = a.mean(axis)
File "C:\Users\alonso\AppData\Local\Programs\Python\Python39\lib\site-packages\numpy\core\_methods.py", line 190, in _mean
ret = ret / rcount
TypeError: unsupported operand type(s) for /: 'map' and 'int'
>>>
Why does this happen? Am I missing something or is an implementation limitation of numpy?
It looks counterintuitive to me that if I map something into floats I have to explicitly convert them into a list before taking the average, shouldn't np.average
already handle that?
CodePudding user response:
Just forget about map
. It provides poor readability and is rarely useful. List comprehensions and generator expressions have made it obsolete.
As for why it doesn't work: Map returns an iterator object in Python-3. It used to be a list in Python-2, which is why this might have worked in the past. However, numpy generally doesn't handle iterators gracefully. Use np.fromiter(map(float, a), dtype=float)
or np.array(list(map(float, a)))
CodePudding user response:
In Python 3, map ceases to return a list object, so if you want a new list and not just something to iterate over, you either need list(map(float, mylist)
or [float(i) for i in lst]