【问题标题】:Can I combine non-adjacent dimensions in a NumPy array without copying data?我可以在不复制数据的情况下在 NumPy 数组中组合不相邻的维度吗?
【发布时间】:2020-04-30 09:36:57
【问题描述】:

我想将 3-D NumPy 数组的第一个维度和最后一个维度合并为一个维度,而不复制数据:

import numpy as np

data = np.empty((3, 4, 5))
data = data.transpose([0, 2, 1])

try:
  # this fails, indicating that it is not possible:
  # AttributeError: incompatible shape for a non-contiguous array
  data.shape = (-1, 4)
except AttributeError:
  # this creates a copy of the data:
  data = data.reshape((-1, 4))

这可能吗?

【问题讨论】:

    标签: python arrays numpy memory reshape


    【解决方案1】:
    In [55]: arr = np.arange(24).reshape(2,3,4)                                                               
    In [56]: arr1 = arr.transpose(2,1,0)                                                                      
    In [57]: arr                                                                                              
    Out[57]: 
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11]],
    
           [[12, 13, 14, 15],
            [16, 17, 18, 19],
            [20, 21, 22, 23]]])
    In [58]: arr1                                                                                             
    Out[58]: 
    array([[[ 0, 12],
            [ 4, 16],
            [ 8, 20]],
    
           [[ 1, 13],
            [ 5, 17],
            [ 9, 21]],
    
           [[ 2, 14],
            [ 6, 18],
            [10, 22]],
    
           [[ 3, 15],
            [ 7, 19],
            [11, 23]]])
    

    查看这些值在 1d 数据缓冲区中的布局方式:

    In [59]: arr.ravel()                                                                                      
    Out[59]: 
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
           17, 18, 19, 20, 21, 22, 23])
    

    比较转置后的顺序:

    In [60]: arr1.ravel()                                                                                     
    Out[60]: 
    array([ 0, 12,  4, 16,  8, 20,  1, 13,  5, 17,  9, 21,  2, 14,  6, 18, 10,
           22,  3, 15,  7, 19, 11, 23])
    

    如果散列值的顺序不同,则无法避免复制。

    reshape 有这个注释:

    您可以将重塑视为首先解开数组(使用给定的 索引顺序),然​​后将 raveled 数组中的元素插入 使用与用于 散开。

    In [63]: arr1.reshape(-1,2)                                                                               
    Out[63]: 
    array([[ 0, 12],
           [ 4, 16],
           [ 8, 20],
           [ 1, 13],
           [ 5, 17],
           [ 9, 21],
           [ 2, 14],
           [ 6, 18],
           [10, 22],
           [ 3, 15],
           [ 7, 19],
           [11, 23]])
    

    【讨论】:

    • 谢谢!我知道transpose()reshape() 可能是不可能的,但我在想也许还有其他操作可以让我这样做。如果确实没有其他解决方案出现,我会让你的答案稍有保留并接受。最后,我设法通过将后续的复制操作从 NumPy 调整到 TensorFlow 来解决我的问题。
    • 无论是通过转置和重塑还是其他方式完成,它仍然需要对底层数据缓冲区进行新的排序。当shapestrides 的组合允许您访问相同的数据缓冲区时,您将获得view。有没有办法以生成Out[63] 的常规方式遍历Out[59]?我不这么认为。
    猜你喜欢
    • 2021-02-24
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 2020-07-15
    • 2020-01-23
    • 1970-01-01
    • 2014-08-01
    • 1970-01-01
    相关资源
    最近更新 更多