我正在尝试将一些数据从SQL(使用pyodbc)读入一个numpy结构化数组(我相信由于多个dtypes需要结构化数组)。
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)
但是这会返回:
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]
有谁知道如何将数据直接返回到具有多个dtypes的str数组中,或者将元组数组转换为多个dtypes的二维数组,还是其他解决方案?
由于
答案 0 :(得分:0)
您的cursor.fetchall
会返回记录列表。记录是'行对象与元组类似,但它们也允许按名称访问列'(http://mkleehammer.github.io/pyodbc/)。虽然课程细节可能不同,但听起来像是一个名字元组。
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表非常相似 - 包含字段和行。它不是2d数组,但按字段名称索引类似于按列号索引2d数组。
pandas
做了类似的事情,虽然它经常使用dtype=object
(就像Python列表的指针一样)。它会跟踪'行'标签。