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

Python 将数据读入具有多个数据类型的结构化数组,python,arrays,numpy,pyodbc,Python,Arrays,Numpy,Pyodbc,我正在尝试将一些数据从SQL(使用pyodbc)读入一个numpy结构化数组(我认为由于有多个数据类型,需要一个结构化数组) 然而,这返回: TypeError: expected a readable buffer object 如果我作为元组加载到数组中 p_data_tuple = np.asarray([tuple(i) for i in p_data], dtype=ndtype) 它可以工作,但是p\u data\u tuple是一个元组数组,与2d数组相反,这意味着我不能使用p

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

然而,这返回:

TypeError: expected a readable buffer object
如果我作为元组加载到数组中

p_data_tuple = np.asarray([tuple(i) for i in p_data], dtype=ndtype)
它可以工作,但是
p\u data\u tuple
是一个元组数组,与2d数组相反,这意味着我不能使用
p\u data\u tuple[0,1]

有人知道我如何将返回的数据直接放入具有多个数据类型的str数组中,或者将元组数组转换为具有多个数据类型的2d数组,或者其他解决方案吗


谢谢你的
光标。fetchall
返回记录列表。记录是“行对象类似于元组,但它们也允许按名称访问列”()。对我来说,听起来像是一个名字的翻版,尽管类的细节可能不同

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')])
这不起作用,大概是因为类似于记录的
元组不是真正的元组

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 cursor记录更接近,但在其他方面没有太多增加

因此,这个结构化数组与源sql表非常相似,有字段和行。它不是二维数组,但按字段名索引类似于按列号索引二维数组


pandas
做了类似的事情,尽管它经常使用
dtype=object
(类似于Python列表的指针)。它跟踪“行”标签。

如果通过pandas运行查询会发生什么:
df=pd.read\u sql\u query(sql\u ps,cnxn)
我可以接受它,然后使用
p\u data\u 2=df.asmatrix(['a','b'))将返回值转换为数组。
但似乎不允许我指定数据类型,对于
p_data_2
来说,它将是
object
“它可以工作,但是p_data_tuple是一个元组数组,与2d数组相反,这意味着我不能使用p_data_tuple[0,1]调用元素”,这就是当您创建结构化数组时发生的情况。它将是一个一维结构阵列。如果结构中字段的数据类型不完全相同,则不能将其作为二维数组进行访问。可以通过数据类型名称访问“列”,例如
data['f1']
。并按数字记录,
data[0]
。谢谢Warren,所以唯一的解决方案大概是将数据读入数组
p\u data=np.asarray(p\u data)
,然后将其切成具有相同数据类型的数组
p_data['a']    # 1d array of floats
p_data['b'][1]  # one string
p_data[10]   # one record