Arrays numpy数组切片:显式/隐式拷贝和内存管理

Arrays numpy数组切片:显式/隐式拷贝和内存管理,arrays,numpy,Arrays,Numpy,这是一个初级python问题,最终与内存管理有关 我将一个uint32 numpy阵列分为两部分,然后尝试创建其中一个子阵列的uint8视图。请注意,通过创建视图,我的意思是在uint8中重新解释内存中的底层数据,而不是在uint8中强制转换变量:因此在这个过程中大小会发生变化 这是初始数组和视图示例,工作正常: a=np.array([(1,2,3,4),(5,6,7,8),(9,10,11,12)],np.int32) a.view(np.int8) # everything is fine

这是一个初级python问题,最终与内存管理有关

我将一个uint32 numpy阵列分为两部分,然后尝试创建其中一个子阵列的uint8视图。请注意,通过创建视图,我的意思是在uint8中重新解释内存中的底层数据,而不是在uint8中强制转换变量:因此在这个过程中大小会发生变化

这是初始数组和视图示例,工作正常:

a=np.array([(1,2,3,4),(5,6,7,8),(9,10,11,12)],np.int32)
a.view(np.int8) # everything is fine
这会崩溃(c不是硬拷贝,仍然绑定到原始阵列):

在创建视图之前删除原始阵列也无济于事:

a=np.array([(1,2,3,4),(5,6,7,8),(9,10,11,12)],np.int32)
c, b= np.split (a,[1],1);
del a
c.view(np.int8) #oups
这是我想到的最好的:

a=np.array([(1,2,3,4),(5,6,7,8),(9,10,11,12)],np.int32)
c, a= np.split (a,[1],1);
c=np.copy(c).view(np.uint8) #ok, but really ?!?

是否有更好的方法将数组分解成2个子数组,以便NUMPY将它们视为“原生”,而不复制它们?(当然,原始数组会被丢弃)

在拆分或切片之前,将
a
作为数据类型
np.int8
查看。那你可以用

In [219]: c, _ = np.split(a.view(np.int8), [4], 1)

In [220]: c
Out[220]: 
array([[1, 0, 0, 0],
       [5, 0, 0, 0],
       [9, 0, 0, 0]], dtype=int8)
或者更简单一点

In [286]: c = a.view(np.int8)[:, :4]
In [287]: c
Out[287]: 
array([[1, 0, 0, 0],
       [5, 0, 0, 0],
       [9, 0, 0, 0]], dtype=int8)

相反。

崩溃不是正确的术语。它只会给出一条错误消息:

ValueError: new type not compatible with array.
忘记“抛弃”原作;拆分产品仍然存在,并使用原始数据缓冲区

如果已沿轴0拆分阵列,则视图将正常工作

In [368]: c0.view(np.int8)
Out[368]: array([[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0]], dtype=int8)
或者如果原件是
order='F'

In [369]: a=np.array([(1,2,3,4),(5,6,7,8),(9,10,11,12)],np.int32,order='F')

In [370]: c,b=np.split(a,[1],1)

In [371]: c.view(np.int8)
Out[371]: 
array([[1],
       [0],
       ...
       [9],
       [0],
       [0],
       [0]], dtype=int8)
如果需要,最后一个可以重塑为(3,4)

这可能有助于可视化原始数据缓冲区中的数字布局

[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12]
您要求的视图是:

[ 1,0,0,0,  2,  3,  4,  5,0,0,0,  6,  7,  8,  9,0,0,0, 10, 11, 12]
它很高兴把整个事情看作是
int8
,而不仅仅是零碎的东西

有了这些备选方案,您将要求以字节的形式查看连续块

[ 1,0,0,0,  2,0,0,0,  3,0,0,0,  4,  5,  6,  7,  8,  9, 10, 11, 12]

好吧,我明白了,我的观点最终变成了不连续的内存块。这意味着我迟早要在内存中转置数组。谢谢
[ 1,0,0,0,  2,0,0,0,  3,0,0,0,  4,  5,  6,  7,  8,  9, 10, 11, 12]