【问题标题】:Read data into structured array with multiple dtypes将数据读入具有多种数据类型的结构化数组
【发布时间】:2016-02-03 10:50:00
【问题描述】:

我正在尝试将 SQL 中的一些数据(使用 pyodbc)读取到一个 numpy 结构化数组中(我相信由于有多种 dtype,需要一个结构化数组)。

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] 调用元素

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

谢谢

【问题讨论】:

  • 如果通过 pandas 运行查询会发生什么:df = pd.read_sql_query(sql_ps, cnxn)
  • 我可以接受它,然后使用 p_data_2 = df.asmatrix(['a','b']) 将返回值转换为数组,但似乎不允许我指定 dtype,对于 p_data_2 将是 object
  • “它可以工作,但是 p_data_tuple 是一个元组数组,而不是二维数组,这意味着我不能使用 p_data_tuple[0,1] 调用元素”当您创建结构化数组时会发生这种情况。它将是一个一维结构数组。如果结构中字段的数据类型不完全相同,则不能将其作为二维数组访问。
  • 您通过数据类型名称访问“列”,例如data['f1']。并按编号记录,data[0]
  • 感谢 Warren,所以大概唯一的解决方案是将数据读入数组 p_data = np.asarray(p_data),然后将其分割成具有相同 dtypes 的数组

标签: python arrays numpy pyodbc


【解决方案1】:

您的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 表非常相似 - 包含字段和行。它不是二维数组,但按字段名索引类似于按列号索引二维数组。

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

【讨论】:

    猜你喜欢
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多