【问题标题】:numpy array slicing: explicit/implicit copies and memory managementnumpy 数组切片:显式/隐式副本和内存管理
【发布时间】:2015-06-17 02:14:15
【问题描述】:

这是一个 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, a= np.split (a,[1],1);
c.view(np.int8) #oups

在创建视图之前放弃原始数组也无济于事:

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 将它们视为“本地”而不复制它们? (当然原来的数组会被丢弃)

【问题讨论】:

    标签: arrays numpy


    【解决方案1】:

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

    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]
    

    【讨论】:

    • 好的,我明白了,我的视图最终出现在不连续的内存块中。这意味着我迟早必须在内存中转置数组。谢谢。
    【解决方案2】:

    a 视为dtype 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)
    

    改为。

    【讨论】:

      猜你喜欢
      • 2021-11-16
      • 2013-01-29
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      • 1970-01-01
      相关资源
      最近更新 更多