如何从可迭代的元组创建多维 numpy 数组?

问题描述 投票:0回答:3

我想从可迭代对象创建一个 numpy 数组,它会产生值的元组,例如数据库查询。

像这样:

data = db.execute('SELECT col1, col2, col3, col4 FROM data')
A = np.array(list(data))

有没有一种更快的方法,无需先将可迭代对象转换为列表?

python python-2.7 numpy
3个回答
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
投票

虽然从技术上讲这不是我问题的答案,但我找到了一种方法来完成我想做的事情:

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

0
投票

我知道这个问题是 10 年前提出的,但我正在尝试做类似的事情,并认为我会分享一个可能的解决方案。使用

chain
(或
chain.from_iterable
)并重塑形状。

from itertools import chain
import numpy as np

NUM_COLS = 3 # or whatever for your data
with db.GetJunk() as cursor:
  data = np.fromiter(chain(*cursor), dtype=float) # or other dtype for your data
num_rows = int(len(data)/NUM_COLS)
data = data.reshape((num_rows, NUM_COLS))
© www.soinside.com 2019 - 2024. All rights reserved.