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

时间:2015-02-15 08:40:50

标签: python python-3.x numpy

在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]

在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>

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

编辑:正如@jonrsharpe在他的回答中指出的那样,如果我先将seq转换为列表,则可以修复此问题:

seq = np.array(list(seq))

但我宁愿避免额外拨打list

2 个答案:

答案 0 :(得分:26)

除了@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])

答案 1 :(得分:9)

虽然您将其称为seq,但Python 3中的map对象 序列(它是一个&#39} iterator ,请参阅what's new in Python 3)。 numpy.array需要一个序列,以便可以确定len并保留适当的内存量;它不会消耗迭代器。例如,{em> 支持大多数序列操作的range对象,可以直接传递;

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

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

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

然而,正如the documentation所说:

  

快速修复是将map()包裹在list()中,例如list(map(...)),但更好的解决方法通常是使用列表理解(特别是当原始代码使用lambda时)

另一种选择是:

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

或只是:

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

或者,实际上从一开始就使用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