将数据读入具有多个dtypes的结构化数组中

时间:2016-02-03 10:50:01

标签: python arrays numpy pyodbc

我正在尝试将一些数据从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的二维数组,还是其他解决方案?

由于

1 个答案:

答案 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列表的指针一样)。它会跟踪'行'标签。