【问题标题】:Appending rows to numpy array using less memory使用更少的内存将行附加到 numpy 数组
【发布时间】:2017-04-30 18:59:51
【问题描述】:

我有以下问题。我需要通过添加行和列来更改一个 Numpy 数组的形状以匹配另一个 Numpy 数组的形状。

假设这是需要更改的数组:

change_array = np.random.rand(150, 120)

这是引用数组:

reference_array = np.random.rand(200, 170)

为了匹配形状,我添加了包含零的行和列,使用以下函数:

def match_arrays(change_array, reference_array):

    cols = np.zeros((change_array.shape[0], (reference_array.shape[1] - change_array.shape[1])), dtype=np.int8)
    change_array = np.append(change_array, cols, axis=1)
    rows = np.zeros(((reference_array.shape[0] - change_array.shape[0]), reference_array.shape[1]), dtype=np.int8)
    change_array = np.append(change_array, rows, axis=0)
    return change_array

完美的工作并将change_array的形状更改为reference_array的形状。但是,使用这种方法,数组需要在内存中复制两次。我了解 Numpy 如何需要在内存中制作数组的副本,以便有空间来追加行和列。

由于我的数组可能变得非常大,我正在寻找另一种内存效率更高的方法,它可以达到相同的结果。谢谢!

【问题讨论】:

    标签: arrays performance numpy memory


    【解决方案1】:

    这里有几种方法。在代码示例中,我将使用以下数组:

    In [190]: a
    Out[190]: 
    array([[12, 11, 15],
           [16, 15, 10],
           [16, 12, 13],
           [11, 19, 10],
           [12, 12, 11]])
    
    In [191]: b
    Out[191]: 
    array([[70, 82, 83, 93, 97, 55],
           [50, 86, 53, 75, 75, 69],
           [60, 50, 76, 52, 72, 88],
           [72, 79, 66, 93, 58, 58],
           [57, 92, 71, 97, 91, 50],
           [60, 77, 67, 91, 91, 63],
           [60, 90, 91, 50, 86, 71]])
    

    使用numpy.pad:

    In [192]: np.pad(a, [(0, b.shape[0] - a.shape[0]), (0, b.shape[1] - a.shape[1])], 'constant')
    Out[192]: 
    array([[12, 11, 15,  0,  0,  0],
           [16, 15, 10,  0,  0,  0],
           [16, 12, 13,  0,  0,  0],
           [11, 19, 10,  0,  0,  0],
           [12, 12, 11,  0,  0,  0],
           [ 0,  0,  0,  0,  0,  0],
           [ 0,  0,  0,  0,  0,  0]])
    

    或者,使用更高效的函数版本,其中结果被预先分配为与reference_array 形状相同的零数组,然后将change_array 中的值复制到结果中:

    In [193]: def match_arrays(change_array, reference_array):
         ...:     result = np.zeros(reference_array.shape, dtype=change_array.dtype)
         ...:     nrows, ncols = change_array.shape
         ...:     result[:nrows, :ncols] = change_array
         ...:     return result
         ...: 
    
    In [194]: match_arrays(a, b)
    Out[194]: 
    array([[12, 11, 15,  0,  0,  0],
           [16, 15, 10,  0,  0,  0],
           [16, 12, 13,  0,  0,  0],
           [11, 19, 10,  0,  0,  0],
           [12, 12, 11,  0,  0,  0],
           [ 0,  0,  0,  0,  0,  0],
           [ 0,  0,  0,  0,  0,  0]])
    

    【讨论】:

    • np.pad 执行 2 concatenates。它为每个轴执行 prependpostpend(总共 4 次操作),但如果 pad 的大小为 0,它足够聪明,可以跳过连接。这是一个用 Python 编写的非常通用的函数。
    猜你喜欢
    • 2017-05-22
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 2020-01-10
    • 1970-01-01
    • 2021-02-21
    • 2021-10-25
    • 2020-03-13
    相关资源
    最近更新 更多