3

我在使用视图方法将字段分配给数组时遇到了一些问题。显然,似乎无法控制您要如何分配该字段。

a=array([[1,2],[1,2],[1,2]]) # 3x2 matrix
#array([[1, 2],
#       [1, 2],
#       [1, 2]])  

aa=a.transpose() # 2x3 matrix
#array([[1, 1, 1],
#       [2, 2, 2]])

a.view(dtype='i8,i8') # This works
a.view(dtype='i8,i8,i8') # This returns error ValueError: new type not compatible with array.
aa.view(dtype='i8,i8') # This works
aa.view(dtype='i8,i8,i8') # This returns error ValueError: new type not compatible with array.

事实上,如果我从头开始创建 aa 而不是使用 a 的转置,

b=array([[1,1,1],[2,2,2]])
b.view(dtype='i8 i8') # This returns ValueError again.
b.view(dtype='i8,i8,i8') # This works

为什么会这样?有什么方法可以设置字段来表示行或列?

4

2 回答 2

2

在 NumPy 中创建标准数组时,一些连续的内存块被数据占用。每个块的大小取决于dtype阵列的形状,这些块的数量和组织。dtype结构化数组遵循相同的模式,不同之处在于每个块现在由几个子块组成,每个子块占用由相应字段定义的一些空间。

在您的示例中,您定义了一个(3,2)整数数组(a)。第一行是 2int个块,第二行是 2 个其他块,第一行是最后 2 个块。如果要将其转换为结构化数组,您可以保留原始布局(每个块成为一个唯一字段a.view(dtype=[('f0', int)]( -block 有一个int大小。这就是你这样做时发生的事情a.view(dtype=[('f0',int),('f1',int)])

您不能制作更大的块(, dtype="i8,i8,i8"),因为相应的信息将分布在不同的行中。

现在,您可以以不同的方式显示您的数组,例如逐列显示它:这就是您执行.transpose数组时发生的情况。不过,它只是显示(NumPy 术语中的“视图”),不会改变原始内存布局。所以,你的aa例子,原来的布局仍然是“3行2个整数”,你可以表示为“3行一个2个整数块”。

在您的第二个示例中b=array([[1,1,1],[2,2,2]]),您有不同的布局:2 行,每行 3int个块。您可以将 3 个 int 块组合成一个更大的块 ( dtype="i8,i8,i8"),因为您不会遍历一行。您不能将其两两分组,因为每行都会有一个额外的块。

您可以(N,M)仅将标准数组转换为 (1) 字段的N结构化数组M或 (2) NxM1 个字段的结构化数组,仅此而已。(N,M)是在创建时赋予数组的形状。您可以(M,N)通过转置将数组显示为数组,但这不会修改原始内存布局。

于 2012-08-30T07:27:16.363 回答
0

当您b.view(dtype='i8, i8')在要求numpy将值重新解释为包含两个值的元组集时指定视图时,但这根本不可行,因为我们有 3 个值不是 2 的倍数,这就像在它所在的位置重塑矩阵会生成一个不同大小的新矩阵,numpy 不喜欢这样的东西。

于 2012-08-30T05:56:03.200 回答