问题所在

前段时间遇到一个问题,在for循环中出现了numpy.float64 object is not iterable的问题,网上一查,发现是个经典问题,大神们的解决方案也不太一样,有的说是因为有numpy的版本过高导致的问题,可以采取降版本的方式(但个人觉得降版本听上去就好麻烦,所以并没有尝试)。查找了半天,也没有看到类似的解决方案,终于摸索出我的问题在哪了。上代码:

for i in range(len(x_mat)):
	x_norm[i] = [math.atan(temp_x)*2/math.pi for temp_x in x_mat[0]]

这里的代码是对一个二维矩阵每一行做相应的处理,若x_mat是二维矩阵,OK!这里代码是可以完美运行,但是当x_mat是一维的时候就报错(因为此时的x_mat[0]是一个数,不能进行循环):

TypeError:numpy.float64 object is not iterable

当然单独写的时候肯定会传入二维矩阵,但是这里为什么会出现一维的情况呢?经过尝试后发现问题,下面是尝试:

>>> x = numpy.array([[1,2,3], [4,5,6]]) # 这里创建一个x.shape = (2,3)的二维矩阵

这里我取出x的第一行:

>>> x0 = x[0]  # x0 = x[0, :]效果一样
>>> x0.shape
OUT: (3,)

这里问题就出现了,其实我是想取出一个二维的矩阵,其shape = (1,3),但是实际取出来的shape = (3, ),这个x0变成了一维数组,跟想象中的不一样啊!!!

解决方案

好的,知道哪里出现坑了,这个时候就要填坑了,即将取出的一维数组变成二维矩阵。
首先,这里用转置无效,因为一维数组转置后还是一维:

>>> a = numpy.transpose(x0)
>>> a.shape
OUT: (3,)

这里给出两个可行方法:

>>> b,c = x0, x0
>>> b.shape = (1, len(b))
>>> b.shape
OUT: (1, 3)
>>> c = c[numpy.newaxis, :] # numpy.newaxis使用方法请自行查阅
>>> c.shape
OUT: (1, 3)

好了,填坑的方法也找到了,去填坑吧!
这里给出一个我的判断数组是否为一维的可行方法:

if len(x0.shape) == 1 # True:一维数组;False:不是一维数组

总结

总结下出现这个问题:
1、出现numpy.float64 object is not iterable错误时,首先查看是否是因为维度出现问题(一般是)。
2、在numpy.array中从二维数组取出某一行时,取出来的数组不是二维数组了,而是变成一维数组了,很有可能使后续程序报错(如循环添加元素,或是拼接矩阵等等)。因此,在取出二维数组后,最好是加一些判断,看看取出的数组维度大小是不是你想要的维度大小。
希望对遇到同样坑的小伙伴有所帮助,同样,有大神有更好更简洁的解决方法,请指教!不胜感激!

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐