元组 NumPy 数据类型
我现在是通过以下方式从SQLite数据库中读取颜色:
import numpy as np, apsw
connection = apsw.Connection(db_name)
cursor = connection.cursor()
desc = {'names':('name','R','G','B'),'formats':('a3','float','float','float')}
colorlist = np.array(cursor.execute("SELECT name, R, G, B FROM Colors").fetchall(),desc)
但我希望能以NumPy数组的形式读取这些数据,只有两列,其中第二列是一个包含(R,G,B)的元组,也就是说,像这样:
desc = {'names':('name','Color'),'formats':('a3','float_tuple')}
colorlist = np.array(cursor.execute("SELECT name, R, G, B FROM Colors").fetchall(),desc)
我想这样做是为了简化我后面提取颜色时的操作,这样我可以直接从数组中以元组的形式提取颜色,而不需要再创建一个字典来帮我处理这些事情:
colorlist[colorlist['name']=='BOS']['Color'][0]
1 个回答
6
你真的需要一个 tuple
吗?还是说你只是想把一些值放在一起?你可以用 numpy 创建一个记录数组,这个数组的每个字段可以有不同的形状...
>>> np.array([('ABC', (1, 2, 3)), ('CBA', (3, 2, 1))], dtype='3a, 3i')
array([('ABC', [1, 2, 3]), ('CBA', [3, 2, 1])],
dtype=[('f0', '|S3'), ('f1', '<i4', 3)])
这甚至适用于 n 维数组:
>>> np.array([('ABC', ((1, 2, 3), (1, 2, 3))), ('CBA', ((3, 2, 1), (3, 2, 1)))],
dtype='a3, (2, 3)i')
array([('ABC', [[1, 2, 3], [1, 2, 3]]), ('CBA', [[3, 2, 1], [3, 2, 1]])],
dtype=[('f0', '|S3'), ('f1', '<i4', (2, 3))])
部分应用到你的具体问题上:
>>> desc = {'names':('name','Color'),'formats':('a3','3f')}
>>> colorlist = np.array([('ABC', (1, 2, 3)), ('CBA', (3, 2, 1))], desc)
>>> colorlist[colorlist['name']=='ABC']['Color'][0]
array([ 1., 2., 3.], dtype=float32)
使用 rec.fromarrays
从两个普通数组生成一个记录数组:
>>> desc = {'names':('name','Color'),'formats':('a3','3f')}
>>> np.rec.fromarrays([['ABC', 'CBA'], [(1, 2, 3), (3, 2, 1)]], desc)[0][1]
array([ 1., 2., 3.], dtype=float32)
一个完整的解决方案:
color_query = cursor.execute("SELECT R, G, B FROM Colors").fetchall()
name_query = cursor.execute("SELECT name FROM Colors").fetchall()
desc = {'names':('name','Color'),'formats':('a3','3f')}
colorlist = np.rec.fromarrays([color_query, name_query], desc)
如果因为某种原因你不能那样拆分查询,你就需要拆分查询的结果,可能可以使用列表推导式来实现:
colorlist = np.rec.fromarrays([[row[0] for row in query],
[row[1:] for row in query]], desc)