如何使用view(numpy)将2D数组转换为结构化数组?

时间:2012-08-30 05:27:44

标签: python view numpy structured-data

我在使用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

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

2 个答案:

答案 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不喜欢这样的东西。

相关问题