numpy fromiter with generator of list

前端 未结 2 1008
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-12 09:03
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 

# W         


        
相关标签:
2条回答
  • 2021-01-12 09:27

    You can only use numpy.fromiter() to create 1-dimensional arrays (not 2-D arrays) as given in the documentation of numpy.fromiter -

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

    Create a new 1-dimensional array from an iterable object.

    One thing you can do is convert your generator function to give out single values from c and then create a 1D array from it and then reshape it to (-1,5) . Example -

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

    Demo -

    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]])
    
    0 讨论(0)
  • 2021-01-12 09:33

    As the docs suggested, np.fromiter() only accepts 1-dimensional iterables. You can use itertools.chain.from_iterable() to flatten the iterable first, and np.reshape() it back later:

    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
    

    Demo:

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

    Only tested on Python 3.6, but should also work with Python 2.

    0 讨论(0)
提交回复
热议问题