【问题标题】:Convert map object to numpy array in python 3在python 3中将地图对象转换为numpy数组
【发布时间】:2015-04-15 22:58:56
【问题描述】:

在 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

【问题讨论】:

  • 我实际上知道list 解决方案,但我问的是直接解决方案。
  • 不转换为list拳头。我忘了提。

标签: python python-3.x numpy


【解决方案1】:

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

【讨论】:

  • fromiter 的例子本质上是这样的:np.fromiter((x*x for x in range(5)),int)
【解决方案2】:

虽然您将其称为 seq,但 Python 3 中的 map 对象不是 序列(它是一个迭代器 ,请参阅what's new in Python 3)。 numpy.array 需要一个序列,因此可以确定 len 并保留适当的内存量;它不会消耗迭代器。比如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

【讨论】:

  • @btel no,np.array 不会使用迭代器。您需要预先提供完整列表,以便保留适当的内存。
猜你喜欢
  • 1970-01-01
  • 2017-06-01
  • 1970-01-01
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多