2016-01-12 63 views
4

我這樣的串聯數據到numpy的陣列的速度:numpy的數組的大小與串聯

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

這樣做是一千倍。該陣列具有D型細胞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的一個基本特徵?

回答

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

是的,整個列表的一個級聯操作比重複的二元操作要好得多。 'concatenate'創建一個正確大小的空結果數組,然後複製每個數據源的數據。一次連接導致更少的副本。 – hpaulj

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數組將被複制到確切的最終目的地,而不是爲每個級聯創建時間數組。