Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert map object to numpy array in python 3

In Python 2 I could do the following:

import numpy as np     f = lambda x: x**2 seq = map(f, xrange(5)) seq = np.array(seq) print seq # prints: [ 0  1  4  9 16] 

In Python 3 it does not work anymore:

import numpy as np     f = lambda x: x**2 seq = map(f, range(5)) seq = np.array(seq) print(seq) # prints: <map object at 0x10341e310> 

How do I get the old behaviour (converting the map results to numpy array)?

Edit: As @jonrsharpe pointed out in his answer this could be fixed if I converted seq to a list first:

seq = np.array(list(seq)) 

but I would prefer to avoid the extra call to list.

like image 992
btel Avatar asked Feb 15 '15 08:02

btel


People also ask

Does map work on NumPy array?

Method 1: numpy.vectorize() function maps functions on data structures that contain a sequence of objects like NumPy arrays. The nested sequence of objects or NumPy arrays as inputs and returns a single NumPy array or a tuple of NumPy arrays.

How do you convert an object to an array in Python?

Using numpy.asarray() , and true (by default) in the case of np. array() . This means that np. array() will make a copy of the object (by default) and convert that to an array, while np.

Can you create a NumPy array of objects?

The array object in NumPy is called ndarray . We can create a NumPy ndarray object by using the array() function.


2 Answers

One more alternative, other than the valid solutions @jonrsharpe already pointed out is to use np.fromiter:

>>> import numpy as np     >>> f = lambda x: x**2 >>> seq = map(f, range(5)) >>> np.fromiter(seq, dtype=np.int) array([ 0,  1,  4,  9, 16]) 
like image 134
Oliver W. Avatar answered Sep 19 '22 19:09

Oliver W.


Although you refer to it as seq, the map object in Python 3 is not a sequence (it's an iterator, see what's new in Python 3). numpy.array needs a sequence so the len can be determined and the appropriate amount of memory reserved; it won't consume an iterator. For example, the range object, which does support most sequence operations, can be passed directly;

seq = np.array(range(5)) print(seq) # prints: [0 1 2 3 4] 

To restore the previous behaviour, as you're aware, you can explicitly convert the map object back to a sequence (e.g. list or tuple):

seq = np.array(list(seq))  # should probably change the name! 

However, as the documentation puts it:

a quick fix is to wrap map() in list(), e.g. list(map(...)), but a better fix is often to use a list comprehension (especially when the original code uses lambda)

So another option would be:

seq = [f(x) for x in range(5)] 

or just:

seq = [x**2 for x in range(5)] 

Alternatively, actually use numpy from the start:

import numpy as np     arr = np.arange(5) arr **= 2 print(arr) # prints [ 0  1  4  9 16] in 2.x and 3.x 
like image 22
jonrsharpe Avatar answered Sep 18 '22 19:09

jonrsharpe