我想从iterable中创建一个numpy数组,它产生值的元组,例如数据库查询。
像这样:
data = db.execute('SELECT col1, col2, col3, col4 FROM data')
A = np.array(list(data))
有没有更快的方法这样做,而不先将iterable转换为列表?
答案 0 :(得分:2)
我不是numpy
的有经验的用户,但这里是一般问题的可能解决方案:
>>> i = iter([(1, 11), (2, 22)])
>>> i
<listiterator at 0x5b2de30> # a sample iterable of tuples
>>> rec_array = np.fromiter(i, dtype='i4,i4') # mind the dtype
>>> rec_array # rec_array is a record array
array([(1, 11), (2, 22)],
dtype=[('f0', '<i4'), ('f1', '<i4')])
>>> rec_array['f0'], rec_array[0] # each field has a default name
(array([1, 2]), (1, 11))
>>> a = rec_array.view(np.int32).reshape(-1,2) # let's create a view
>>> a
array([[ 1, 11],
[ 2, 22]])
>>> rec_array[0][1] = 23
>>> a # a is a view, not a copy!
array([[ 1, 23],
[ 2, 22]])
我假设所有列都属于同一类型,否则rec_array已经是你想要的了。
关于您的具体情况,我并不完全理解您示例中db
的内容。如果它是一个游标对象,那么你可以调用它的fetchall
方法并获得一个元组列表。在大多数情况下,数据库库不希望保留部分读取的查询结果,等待代码处理每一行,即execute
方法返回时,所有数据都已存储在列表中,并且几乎没有问题使用fetchall
而不是迭代cursor
实例。
答案 1 :(得分:1)
虽然从技术上讲不是我的问题的答案,但我找到了一种方法来做我想做的事情:
def get_cols(db, cols):
def get_col(col):
data = db.execute('SELECT '+col+' FROM data', dtype=np.float64)
return np.fromiter((v[0] for v in data))
return np.vstack([get_col(col) for col in cols]).T