将数据读入具有多个数据类型的结构化数组

Read data into structured array with multiple dtypes

我正在尝试从 SQL(使用 pyodbc)读取一些数据到一个 numpy 结构化数组中(我认为由于有多个数据类型,所以需要一个结构化数组)。

import pyodbc
import numpy as np
cnxn = pyodbc.connect('DRIVER={SQL Server};Server=SERVER;Database=DB;Trusted_Connection=Yes;')
cursor = cnxn.cursor()
sql_ps = "select a, b from table"
cursor.execute(sql_positions)
p_data = cursor.fetchall()
cnxn.close

ndtype = np.dtype([('f1','>f8'),('f2','|S22')])
p_data = np.asarray(p_data, dtype=ndtype)

然而这个returns:

TypeError: expected a readable buffer object

如果我将数组作为元组加载到数组中

p_data_tuple = np.asarray([tuple(i) for i in p_data], dtype=ndtype)

它有效,但是 p_data_tuple 是一个元组数组,而不是二维数组,这意味着我不能使用 p_data_tuple[0,1]

调用元素

有谁知道我如何将返回的数据直接放入具有多个数据类型的 str 数组,或将元组数组转换为多个数据类型的二维数组,或其他解决方案?

谢谢

您的 cursor.fetchall returns 记录列表。一条记录是 'Row objects are similar to tuples, but they also allow access to columns by name' (http://mkleehammer.github.io/pyodbc/)。对我来说听起来像是一个 namedtuple,尽管 class 细节可能不同。

sql_ps = "select a, b from table"
cursor.execute(sql_positions)
p_data = cursor.fetchall()
cnxn.close

只是为了好玩,让我们更改 dtype 以使用与 sql 相同的字段名称:

ndtype = np.dtype([('a','>f8'),('b','|S22')])

这不起作用,大概是因为 tuple-like 记录不是真正的元组。

p_data = np.array(p_data, dtype=ndtype)

因此,我们将每条记录转换为一个元组。结构化数组将它们的数据作为元组列表。

p_data = np.array([tuple(i) for i in p_data], dtype=ndtype)

现在您可以按字段或按行访问数据

p_data['a']    # 1d array of floats
p_data['b'][1]  # one string
p_data[10]   # one record

来自 p_data 的记录显示为一个元组,尽管它实际上像父数组一样具有 dtype

结构化数组有一个变体,recarray 它增加了通过属性名称访问字段的能力,例如p_rec.a。这甚至更接近 dp 游标记录,但不会增加太多。

所以这个结构化数组与您的来源非常相似 sql table - 具有字段和行。它不是二维数组,但按字段名索引类似于按列号索引二维数组。

pandas 做类似的事情,尽管它经常求助于使用 dtype=object(就像 Python 列表的指针)。它会跟踪 'row' 个标签。