我在numpy中遇到了以下奇怪的东西,可能是也可能不是bug:
import numpy as np
dt = np.dtype([('tuple', (int, 2))])
a = np.zeros(3, dt)
type(a['tuple'][0]) # ndarray
type(a[0]['tuple']) # ndarray
a['tuple'][0] = (1,2) # ok
a[0]['tuple'] = (1,2) # ValueError: shape-mismatch on array construction
我本以为下面的两个选项都有效。 意见?在
我是在numpy讨论列表上问的。特拉维斯·奥列芬特回答here。在
引用他的回答:
对此的解释见a numpy bug report。在
这是一个上游错误,从NumPy PR #5947开始修复,在1.9.3中进行了修复。在
我得到的错误与您不同(使用numpy 1.7.0.dev):
所以下面的解释可能对您的系统不正确(或者对我所看到的可能是错误的解释)。在
首先,注意索引structured array的一行会得到一个
^{pr2}$numpy.void
对象(请参见data type docs)据我所知,
void
有点像Python列表,因为它可以保存不同数据类型的对象,这是有意义的,因为结构化数组中的列可以是不同的数据类型。在如果不是索引,而是切掉第一行,则会得到一个
ndarray
:这类似于Python列表的工作方式:
切片返回原始序列的缩短版本,但索引返回一个元素(这里是
int
;上面是void
类型)。在因此,当您对结构化数组的行进行切片时,应该希望它的行为与原始数组相同(只是行数较少)。继续您的示例,现在可以为第一行的“tuple”列赋值:
所以,。。。为什么
a[0]['tuple'] = (1, 2)
不起作用?在好吧,回想一下
a[0]
返回一个void
对象。所以,当你打电话您将一个
tuple
分配给void
对象的“tuple”元素。注意:尽管您将此索引称为“元组”,但它存储为ndarray
:所以,这意味着元组需要转换成
ndarray
。但是,void
对象不能强制转换赋值(这只是猜测),因为它可以包含任意的数据类型,所以它不知道要转换到什么类型。要解决这一问题,您可以自己投射输入:事实上我们得到了不同的错误,这表明上面的一行可能不适合您,因为casting处理的是我收到的错误,而不是您收到的错误。在
附录:
那么,为什么下面的工作呢?在
在这里,当您添加
[:]
时,您将索引到数组中,但是如果没有这个,您将索引到void
对象。换句话说,a[0]['tuple'][:]
表示“替换存储数组的元素”(由数组处理),a[0]['tuple']
表示“替换存储数组”(由void
处理)。在结语:
奇怪的是,访问行(即用0索引)似乎会删除基数组,但它仍然允许您分配给基数组。在
也许
void
不是真正的数组,所以它没有基数组,。。。但是为什么它有一个base
属性?在相关问题 更多 >
编程相关推荐