gpt4 book ai didi

python - 将 MySQL 结果集转换为 NumPy 数组的最有效方法是什么?

转载 作者:太空狗 更新时间:2023-10-29 17:09:46 25 4
gpt4 key购买 nike

我正在使用 MySQLdb 和 Python。我有一些基本的查询,例如:

c=db.cursor()
c.execute("SELECT id, rating from video")
results = c.fetchall()

我需要将“结果”作为 NumPy 数组,并且我希望在内存消耗方面保持经济。看起来逐行复制数据的效率非常低(需要双倍的内存)。有没有更好的方法将MySQLdb查询结果转换成NumPy数组格式?

我希望使用 NumPy 数组格式的原因是因为我希望能够轻松地对数据进行切片和切 block ,而在这方面,python 似乎对多维数组不是很友好。

e.g. b = a[a[:,2]==1] 

谢谢!

最佳答案

这个方案使用了Kieth的fromiter技术,但是对SQL结果的二维表结构的处理更加直观。此外,它通过避免 python 数据类型中的所有 reshape 和展平来改进 Doug 的方法。使用 structured array我们几乎可以直接从 MySQL 结果读取到 numpy,几乎 完全去除 python 数据类型。我说“几乎”是因为 fetchall 迭代器仍然生成 python 元组。

虽然有一个警告,但这不是什么大问题。您必须事先知道列的数据类型和行数。

知道列类型应该是显而易见的,因为您大概知道查询是什么,否则您始终可以使用 curs.description 和 MySQLdb.FIELD_TYPE.* 常量的映射。

知道行数意味着您必须使用客户端游标(这是默认设置)。我对 MySQLdb 和 MySQL 客户端库的内部结构知之甚少,但我的理解是,当使用客户端游标时,整个结果都被提取到客户端内存中,尽管我怀疑实际上涉及一些缓冲和缓存。这意味着对结果使用双倍内存,一次用于游标复制,一次用于数组复制,因此如果结果集很大,尽快关闭游标以释放内存可能是个好主意。

严格来说,您不必提前提供行数,但这样做意味着数组内存会提前分配一次,而不是随着更多行从迭代器进入而不断调整大小,这意味着提供巨大的性能提升。

然后,一些代码

import MySQLdb
import numpy

conn = MySQLdb.connect(host='localhost', user='bob', passwd='mypasswd', db='bigdb')
curs = conn.cursor() #Use a client side cursor so you can access curs.rowcount
numrows = curs.execute("SELECT id, rating FROM video")

#curs.fetchall() is the iterator as per Kieth's answer
#count=numrows means advance allocation
#dtype='i4,i4' means two columns, both 4 byte (32 bit) integers
A = numpy.fromiter(curs.fetchall(), count=numrows, dtype=('i4,i4'))

print A #output entire array
ids = A['f0'] #ids = an array of the first column
#(strictly speaking it's a field not column)
ratings = A['f1'] #ratings is an array of the second colum

请参阅有关 dtype 的 numpy 文档和上面关于结构化数组的链接,了解如何指定列数据类型和列名称。

关于python - 将 MySQL 结果集转换为 NumPy 数组的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7061824/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com