使用更少的内存将行添加到numpy数组

时间:2016-12-15 08:35:54

标签: arrays performance numpy memory

我有以下问题。我需要通过添加行和列来更改一个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如何在内存中制作数组的副本,以便有空间来追加行和列。

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

1 个答案:

答案 0 :(得分: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]])