我在使用view方法将字段分配给数组时遇到了一些问题。显然,似乎没有控制你想如何分配字段。
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
为什么会这样?有什么办法可以设置字段来表示行或列吗?
答案 0 :(得分:2)
在NumPy中创建标准数组时,数据会占用一些连续的内存块。每个块的大小取决于dtype
,这些块的数量和组织由阵列的形状决定。结构化数组遵循相同的模式,除了每个块现在由几个子块组成,每个子块占据由相应的dtype
字段定义的空间。
在您的示例中,您定义了一个(3,2)
整数数组(a
)。对于第一行,这是2 int
块,然后是第二行的2个其他块,然后是第一行的最后2个块。如果要将其转换为结构化数组,可以保留原始布局(每个块变为唯一字段(a.view(dtype=[('f0', int)]
),或将2块行转换为1个较大块的行,包括2个子块-blocks,每个子块具有int
大小。
这就是你a.view(dtype=[('f0',int),('f1',int)])
时发生的事情。
您不能制作更大的块(即,dtype="i8,i8,i8"
),因为相应的信息将分布在不同的行中。
现在,您可以以不同的方式显示数组,例如逐列显示数组:这是您执行数组的.transpose
时发生的情况。但它只是显示(NumPy术语中的“视图”),它不会改变原始内存布局。所以,你的aa
例子,原始布局仍然是“3行2个整数”,你可以表示为“2个整数的一个块的3行”。
在第二个示例b=array([[1,1,1],[2,2,2]])
中,您有不同的布局:2行3 int
块。您可以将3个int块分组为一个更大的块(dtype="i8,i8,i8"
),因为您没有超过一行。你不能将它分为两个,因为每行都会有一个额外的块。
您可以将(N,M)
标准数组转换为(1)N
结构化M
字段数组或(2){1}}结构化数组1字段,就是这样。 NxM
是数组在创建时赋予的形状。您可以通过转置将数组显示为(N,M)
数组,但这不会修改原始内存布局。
答案 1 :(得分:0)
当您将视图指定为b.view(dtype='i8, i8')
时,您要求numpy
将值重新解释为具有两个值的元组集,但这简直是不可行的,因为我们有3个值不是' t是2的倍数,就像重塑矩阵一样,它会生成一个不同大小的新矩阵,numpy不喜欢这样的东西。