2015-08-24 46 views
1

我有一個矩陣M與維度(m, n),我需要添加新的列從矩陣L與維度(m, l)。所以基本上我會以矩陣(m, n + l)結束。如何將追加到一個numpy數組而不重新分配結果到一個新的變量?

在做這個沒問題,我可以使用:

以下列方式np.command(M, L),它將返回我一個新的矩陣。這個問題出現在我需要將許多矩陣附加到原始矩陣的事實上,並且這些矩陣L的大小事先是未知的。

所以我結束了

# M is my original matrix 
while: 
    # find out my L matrix 
    M = np.append(M, L) 
    # check if I do not need to append the matrix 

知道,我的矩陣M有大約10萬行,我想補充平均5K列,這個過程是非常緩慢的,不是幾個小時需要花費更多的(我不不知道究竟是多久,因爲我在2小時後放棄了)。

這裏的問題很明顯是在這append函數中(我試過用vstack並沒有改變)。此外,如果我只是計算矩陣L(不附加它們),我花費不到10分鐘的任務。我認爲這個矩陣的重新分配是讓它變慢的原因。直覺上它是有道理的,因爲我不斷重新創建矩陣M並刪除舊的矩陣。但我不知道如何擺脫重新分配的部分。

一個想法是,事先創建一個空矩陣,然後填充正確的列應該是更快,但問題是,我不知道我應該創建它的尺寸(沒有辦法預測的數量列在我的矩陣)。

那麼我該如何提高性能呢?

+4

在程序中重複添加迭代是否重要?如果不是,你可以收集所有的矩陣,然後一次加入所有的矩陣。 – cel

+0

追加,vstack等全部使用連接 – hpaulj

回答

3

如果不創建副本,則無法追加到現有的numpy陣列。

原因是numpy數組必須由連續的內存塊支持。如果我創建了一個(1000, 10)數組,然後決定要追加另一行,我需要能夠擴展與該數組相對應的RAM塊,以便它足夠大以容納(1001, 10)元素。在一般情況下,這是不可能的,因爲相鄰的內存地址可能已經被分配給其他對象。

「連接」數組的唯一方法是讓操作系統爲新數組分配足夠大的內存塊,然後將原始數組的內容和新行復制到此空間中。如果你在一個循環中重複執行它,這顯然是非常低效的,尤其是當你的數組越來越大時,複製步驟變得越來越昂貴。

這裏有兩個可能的變通:

  1. 使用標準的Python列表積累你的while循環中的行,則列表轉換爲一個數組中的一個步驟,外循環。附加到Python列表與連接numpy數組相比非常便宜,因爲列表只是一個指針數組,不一定需要引用相鄰的內存地址,因此不需要進行復制。

  2. 對最終數組中的行數進行有根據的猜測,然後分配一個稍大的numpy數組並填入行。如果空間不足,則在另一行的行上進行連接。很顯然,級聯步驟很昂貴,因爲你需要複製一次,但是在你循環的每次迭代中,你最好做一次或兩次。當您在輸出數組中選擇行的初始數量時,會避免過度分配和不必要的級聯步驟之間的權衡。一旦你完成了,你可以使用切片索引來「修剪」任何未使用的行。

相關問題