numpy数组大小与连接速度

时间:2016-01-12 15:19:03

标签: python performance numpy

我将数据连接到像这样的numpy数组:

xdata_test = np.concatenate((xdata_test,additional_X))

这已经完成了一千次。数组的类型为float32,其大小如下所示:

xdata_test.shape   :  (x1,40,24,24)        (x1 : [500~10500])   
additional_X.shape :  (x2,40,24,24)        (x2 : [0 ~ 500])

问题是当x1大于~2000-3000时,连接需要更长的时间。

下图显示了连接时间与x2维度的大小:

x2 vs time consumption

这是一个记忆问题还是numpy的基本特征?

2 个答案:

答案 0 :(得分:6)

据我了解numpy,所有stackconcatenate函数效率都不高。并且有充分的理由,因为numpy试图保持数组内存的连续效率(参见this link about contiguous arrays in numpy

这意味着每次连接操作都必须每次都复制整个数据。当我需要将一堆元素连接在一起时,我倾向于这样做:

l = []
for additional_X in ...:
    l.append(addiional_X)
xdata_test = np.concatenate(l)

这样,移动整个数据的昂贵操作只进行一次。

注意:对提供给你的速度提升感兴趣。

答案 1 :(得分:5)

如果您预先连接了要连接的数组,我建议创建一个具有总形状的新数组,并用小数组填充它而不是连接,因为每个连接操作都需要将整个数据复制到新的连续的记忆空间。

  • 首先,计算第一轴的总大小:

    max_x = 0
    for arr in list_of_arrays:
        max_x += arr.shape[0]
    
  • 其次,创建最终容器:

    final_data = np.empty((max_x,) + xdata_test.shape[1:], dtype=xdata_test.dtype)
    

    相当于(max_x, 40, 24, 24)但动态输入。

  • 最后,填写numpy数组:

    curr_x = 0
    for arr in list_of_arrays:
        final_data[curr_x:curr_x+arr.shape[0]] = arr
        curr_x += arr.shape[0]
    

上面的循环将每个数组复制到较大数组的先前定义的列/行中。

通过这样做,每个N数组都将被复制到确切的最终目标,而不是为每个连接创建时间数组。