在python 3中将map对象转换为numpy数组

bte*_*tel 24 python numpy python-3.x

在Python 2中,我可以执行以下操作:

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]
Run Code Online (Sandbox Code Playgroud)

在Python 3中,它不再起作用了:

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>
Run Code Online (Sandbox Code Playgroud)

如何获得旧行为(将map结果转换为numpy数组)?

编辑:正如@jonrsharpe在他的回答中指出的那样,如果我先转换seq成一个列表,这可以修复:

seq = np.array(list(seq))
Run Code Online (Sandbox Code Playgroud)

但我宁愿避免额外的电话list.

Oli*_* W. 30

除了@jonrsharpe已经指出的有效解决方案之外,还有一个替代方案是使用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])
Run Code Online (Sandbox Code Playgroud)


jon*_*rpe 8

虽然你称之为,但Python 3中seqmap对象不是一个序列(它是一个迭代器,请参阅Python 3中的新内容).numpy.array需要一个序列,以便len可以确定并保留适当的内存量; 它不会消耗迭代器.例如,range对象,它支持大多数序列的操作,可以被直接传递;

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

要恢复以前的行为,如您所知,您可以显式地将map对象转换回序列(例如列表或元组):

seq = np.array(list(seq))  # should probably change the name!
Run Code Online (Sandbox Code Playgroud)

但是,正如文件所说:

速战速决是包装map()list(),如list(map(...)),但更好的解决办法是经常使用列表理解(尤其是当原来的代码使用lambda)

所以另一种选择是:

seq = [f(x) for x in range(5)]
Run Code Online (Sandbox Code Playgroud)

要不就:

seq = [x**2 for x in range(5)]
Run Code Online (Sandbox Code Playgroud)

或者,实际上numpy从一开始就使用:

import numpy as np    
arr = np.arange(5)
arr **= 2
print(arr)
# prints [ 0  1  4  9 16] in 2.x and 3.x
Run Code Online (Sandbox Code Playgroud)