如何从生成器中构建一个numpy数组?

问题:

如何从生成器对象中构建一个numpy数组?
让我来说明问题:

>>> import numpy
>>> def gimme():
...   for x in xrange(10):
...     yield x
...
>>> gimme()
<generator object at 0x28a1758>
>>> list(gimme())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> numpy.array(xrange(10))
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> numpy.array(gimme())
array(<generator object at 0x28a1758>, dtype=object)
>>> numpy.array(list(gimme()))
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

在这种情况下,gimme()是我想要转换成数组的生成器。然而,数组构造函数不会遍历生成器,它只是存储生成器本身。我希望的行为是从numpy.array(list(gimme())),但是我不想支付在内存中同时拥有中间列表和最终数组的内存开销。有更节省空间的方式吗?

回答:

Numpy数组需要在创建时明确设置它们的长度,这与python列表不同。这是必要的,因此每个项目的空间可以连续分配到内存中。连续分配是numpy数组的关键特性:与本地代码实现相结合,使得它们的操作比常规列表执行得更快。
记住这一点,在技术上不可能使用生成器对象并将其转换为数组,除非您:

  1. 可以预测运行时将产生多少元素:
      my_array = numpy.empty(predict_length())
    对于我,枚举中的el(gimme()):my_array [i] = el
  2. 愿意将其元素存储在中间列表中:
      my_array = numpy.array(list(gimme()))
  3. 可以使两个相同的生成器,通过第一个生成器来查找总长度,初始化数组,然后再次运行通过生成器来查找每个元素:
      length = sum(gimme()中为1)
    my_array = numpy.empty(length)
    对于我,枚举中的el(gimme()):my_array [i] = el

 1可能是您正在寻找的。 2空间无效,3是时间无效的(你必须经过生成器两次)。

 
 
Code问答: http://codewenda.com/topics/python/
Stackoverflow: How do I build a numpy array from a generator?

*转载请注明本文链接以及stackoverflow的英文链接

发表评论

电子邮件地址不会被公开。 必填项已用*标注

− 2 = 6