【问题标题】:numpy fromiter with generator of list带有列表生成器的 numpy fromiter
【发布时间】:2016-01-04 23:20:59
【问题描述】:
import numpy as np
def gen_c():
    c = np.ones(5, dtype=int)
    j = 0
    t = 10
    while j < t:
        c[0] = j
        yield c.tolist()
        j += 1 

# What I did:
# res = np.array(list(gen_c())) <-- useless allocation of memory

# this line is what I'd like to do and it's killing me
res = np.fromiter(gen_c(), dtype=int) # dtype=list ?

错误说ValueError: setting an array element with a sequence.

这是一段非常愚蠢的代码。我想从生成器创建一个列表数组(最后是一个二维数组)...

虽然我到处搜索,但我仍然无法弄清楚如何让它工作。

【问题讨论】:

    标签: python arrays numpy generator


    【解决方案1】:

    您只能使用numpy.fromiter() 来创建documentation of numpy.fromiter 中给出的一维数组(不是二维数组)-

    numpy.fromiter(iterable, dtype, count=-1)

    从一个可迭代对象创建一个新的一维数组。

    您可以做的一件事是将您的生成器函数转换为从 c 发出单个值,然后从中创建一个一维数组,然后将其重塑为 (-1,5) 。示例 -

    import numpy as np
    def gen_c():
        c = np.ones(5, dtype=int)
        j = 0
        t = 10
        while j < t:
            c[0] = j
            for i in c:
                yield i
            j += 1
    
    np.fromiter(gen_c(),dtype=int).reshape((-1,5))
    

    演示 -

    In [5]: %paste
    import numpy as np
    def gen_c():
        c = np.ones(5, dtype=int)
        j = 0
        t = 10
        while j < t:
            c[0] = j
            for i in c:
                yield i
            j += 1
    
    np.fromiter(gen_c(),dtype=int).reshape((-1,5))
    
    ## -- End pasted text --
    Out[5]:
    array([[0, 1, 1, 1, 1],
           [1, 1, 1, 1, 1],
           [2, 1, 1, 1, 1],
           [3, 1, 1, 1, 1],
           [4, 1, 1, 1, 1],
           [5, 1, 1, 1, 1],
           [6, 1, 1, 1, 1],
           [7, 1, 1, 1, 1],
           [8, 1, 1, 1, 1],
           [9, 1, 1, 1, 1]])
    

    【讨论】:

    • 再次感谢您!你回答了我所有的两个问题:D
    • 很高兴能提供帮助! :-)
    • PS:事实上,这个解决方案(我不是说你的,我说的是我的)在我的情况下并没有提高性能......
    • 是的,因为c.tolist() 比循环通过c 并产生每个值要快得多
    【解决方案2】:

    正如文档所建议的,np.fromiter() 仅接受一维迭代。 您可以先使用itertools.chain.from_iterable() 将可迭代对象展平,然后再使用np.reshape() 将其返回:

    import itertools
    import numpy as np
    
    def fromiter2d(it, dtype):
    
        # clone the iterator to get its length
        it, it2 = itertools.tee(it)
        length = sum(1 for _ in it2)
    
        flattened = itertools.chain.from_iterable(it)
        array_1d = np.fromiter(flattened, dtype)
        array_2d = np.reshape(array_1d, (length, -1))
        return array_2d
    

    演示:

    >>> iter2d = (range(i, i + 4) for i in range(0, 12, 4))
    
    >>> from_2d_iter(iter2d, int)
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    

    仅在 Python 3.6 上测试,但也应适用于 Python 2。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-16
      • 1970-01-01
      • 2020-01-22
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 2013-11-27
      相关资源
      最近更新 更多