Numpy ValueError:使用序列

时间:2015-09-22 17:01:54

标签: python numpy

我试图将mysql数据转换为numpy数组(最终是一个列表)时得到Numpy ValueError: setting an array element with a sequence。最初我想拥有多个字段,但我已经将代码简化为仅使用一个字段(整数)创建列表以进行故障排除。

我是numpy的新手,所以我不确定i4代表什么(虽然文档说这意味着整数......好吧)。对于count,这似乎是指字段数。但是,fromiter行上的某些内容仍然会导致它出现异常。

import MySQLdb
import numpy

conn = MySQLdb.connect(host="localhost", user="x", passwd="x", db="x")
curs = conn.cursor() 
numrows = curs.execute("select id from table")

A = numpy.fromiter(curs.fetchall(), count=numrows, dtype=('i4'))

print A 
ids = A['f0'] 

回溯:

A = numpy.fromiter(curs.fetchall(), count=1, dtype=('i4'))
ValueError: setting an array element with a sequence.

1 个答案:

答案 0 :(得分:2)

更正 - 使用来自fetchall的元组列表,dtype应生成结构化数组

查看文档,我看到fetch_all返回元组列表,而不是生成器。但这不是问题。两者都是可迭代的。问题在于dtype。要从元组列表中创建一个1d数组,fromiter需要一个结构化的复合dtype。

此dtype适用于1元素元组:

In [355]: np.fromiter([(1,)],dtype=[('f0','i4')])
Out[355]: 
array([(1,)], dtype=[('f0', '<i4')])

这适用于2个字段(列)

In [356]: np.fromiter([(1,1)],dtype=('i4,i4'))
Out[356]: 
array([(1, 1)],   dtype=[('f0', '<i4'), ('f1', '<i4')])

但这些是相同的 - 一个简单的非结构化数组。

np.fromiter([(1,)],dtype=('i4'))
np.fromiter([(1,)],dtype=int)

[(1,)]的处理方式与[[1]]相同,即{2}数组的输入,而不是fromiter期望的1d可迭代。

对于结构化案例,

np.arrayfromiter的作用相同:

 np.array([(1,)],dtype=[('f0','i4')])
 np.array([(1,1)],dtype=('i4,i4'))

它也适用于int(或i4),但结果是二维数组:

In [366]: np.array([(1,)],dtype=('i4'))
Out[366]: array([[1]])

(早期版本)

我可以通过fromiter [(1,)]可迭代来重现您的错误消息。

In [288]: np.fromiter([(1,)],dtype=int)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-288-ba24373a9489> in <module>()
----> 1 np.fromiter([(1,)],dtype=int)

ValueError: setting an array element with a sequence.

fromiter想要输入1d,例如[1,2,3](或等效的生成器)。

自从我使用sql以来已经有一段时间了,但我的猜测是curs.fetchall()给出了一个可迭代的元组,而不是单个数字的可迭代。

您需要显示(打印)curs.fetchall()list(curs.fetchall())以查看传递给fromiter的内容。

您为什么使用fromiter?你试过np.array(curs.fetchall())吗?

让我们尝试使用生成器表达式来更好地模拟生成元组的fetchall

In [298]: np.fromiter((i for i in [(1,2,3)]),dtype=int)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-298-f8fbf106b4d1> in <module>()
----> 1 np.fromiter((i for i in [(1,2,3)]),dtype=int)

ValueError: setting an array element with a sequence.
In [299]: np.array((i for i in [(1,2,3)]),dtype=int)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-299-71dd7463b539> in <module>()
----> 1 np.array((i for i in [(1,2,3)]),dtype=int)

TypeError: int() argument must be a string or a number, not 'generator'

这有效:

In [300]: np.array(list(i for i in [(1,2,3)]),dtype=int)
Out[300]: array([[1, 2, 3]])

In [301]: list(i for i in [(1,2,3)])
Out[301]: [(1, 2, 3)]

创建numpy数组的最简单方法是使用列表 - 它可以是数字列表,列表列表(所有相同大小)或元组列表。

What's the most efficient way to convert a MySQL result set to a NumPy array?是之前关于使用fetchallfromiter的讨论。