2015-10-07 32 views
1
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 ? 

的發電機numpy的fromiter錯誤所述ValueError: setting an array element with a sequence.與列表

這是一個非常笨一段代碼。我想從一個發電機創建列表的數組(最後一個二維陣列)...

雖然我到處找,我仍然無法弄清楚如何使它發揮作用。

回答

3

只能使用numpy.fromiter()documentation of numpy.fromiter賦予創建的一維數組(未2- d陣列) -

numpy.fromiter(可迭代,D型細胞,計數= -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]]) 
+0

工作再次感謝你!你回答了所有我的兩個問題:d – XXXXXL

+0

總是很高興有幫助! :-) –

+1

PS:其實,這個解決方案(我不是說你的,我說的是我的)沒有改善我的情況下的表現...... – XXXXXL

0

作爲文檔建議,np.fromiter()只接受1維iterables。 您可以使用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