2016-04-11 88 views
1

我讀了關於預分配numpy數組的重要性。然而,在我的情況下,我不知道如何做到這一點。我想預先分配一個nxm矩陣。這聽起來很簡單numpy數組的numpy數組的預分配

M = np.zeros((n,m)) 

但是,如果我的矩陣是矩陣矩陣?那麼,如果每個nxm元素實際上是什麼形式的呢?我知道在這種情況下,M的形狀是(n,m,3)。 作爲一個例子,後來我想有這樣的事情

[[[[0], [0,1,2], [3,4,5]], 
    [[1], [10,11,12], [13,14,15]]], 
[[[0], [100,101,102], [103,104,105]], 
    [[1], [110,111,112], [113,114,115]]]] 

我試圖簡單地做

M = np.zeros((2,2,3)) 

但隨後

M[0,0,:] = np.array([[0], [0,1,2], [3,4,5]]) 

會給我一個錯誤

ValueError: setting an array element with a sequence.

Ca ñ我不預先分配這個怪物?或者我應該以完全不同的方式來解決這個問題?

感謝您的幫助

+0

您的示例將不起作用,因爲您在'np.array'調用中忘記了封閉的'[]'。也請使用實數而不是未定義的變量,以便更容易地看到你想要的。目前,每個't','x000'都可以是一個數字或一個numpy數組,或者完全是別的。另請參閱:[mcve] – MSeifert

+0

謝謝,'[]'不幸不是缺少的。我編輯了這個例子,我也發現我需要'M.shape =(m,n,3)'。但它仍然行不通。 – grinsbaeckchen

+0

爲什麼不只是收集陣列上的列表? – hpaulj

回答

0

您必須確保在每個維度上預先分配正確數量的維度和元素,以便使用簡單分配來填充它。

例如要保存3個2x3矩陣:

number_of_matrices = 3 
matrix_dim_1 = 2 
matrix_dim_2 = 3 

M = np.empty((number_of_matrices, matrix_dim_1, matrix_dim_2)) 
M[0] = np.array([[ 0, 1, 2], [ 3, 4, 5]]) 
M[1] = np.array([[100, 101, 102], [103, 104, 105]]) 
M[2] = np.array([[ 10, 11, 12], [ 13, 14, 15]]) 

M 
#array([[[ 0., 1., 2.],   # matrix 1 
#  [ 3., 4., 5.]], 
# 
#  [[ 100., 101., 102.],   # matrix 2 
#  [ 103., 104., 105.]], 
# 
#  [[ 10., 11., 12.],   # matrix 3 
#  [ 13., 14., 15.]]]) 

你的方法包含了一些問題。要保存的陣列是不是一個有效的n維數組numpy的:

np.array([[0], [0,1,2], [3,4,5]]) 
# array([[0], [0, 1, 2], [3, 4, 5]], dtype=object) 
#         |----!!----| 
#   ^-------^----------^  3 items in first dimension 
#  ^      1 item in first item of 2nd dim 
#    ^--^--^    3 items in second item of 2nd dim 
#       ^--^--^ 3 items in third item of 2nd dim  

它只是創建了一個包含蟒蛇list對象的3項數組。你可能想要一個包含數字的數組,所以你需要關心維度。您的np.array([[0], [0,1,2], [3,4,5]])可能是3x1陣列或3x3陣列,numpy不知道在這種情況下要做什麼並將其保存爲對象(該陣列現在只有1維!)。


另一個問題是,你想設置預分配數組的一個元素與另一個包含多個元素的數組。這是不可能的(除非你已經有一個object-陣列)。你這裏有兩種選擇:

  1. 填補了預分配的數組中的元素數由陣列所需:

    M[0, :, :] = np.array([[0,1,2], [3,4,5]]) 
    # ^--------------------^--------^  First dimension has 2 items 
    #  ^---------------^-^-^   Second dimension has 3 items 
    #  ^------------------------^-^-^ dito 
    # if it's the first dimension you could also use M[0] 
    
  2. 創建object陣列和設置元素(不推薦這樣做,最鬆的numpy的陣列)的優點是:

    M = np.empty((3), dtype='object') 
    M[0] = np.array([[0,1,2], [3,4,5]]) 
    M[1] = np.array([[0,1,2], [3,4,5]]) 
    M[2] = np.array([[0,1,2], [3,4,5]]) 
    M 
    #array([array([[0, 1, 2], 
    #    [3, 4, 5]]), 
    #  array([[0, 1, 2], 
    #    [3, 4, 5]]), 
    #  array([[0, 1, 2], 
    #    [3, 4, 5]])], dtype=object) 
    
+0

好吧,我想我將不得不重新思考我的整個問題,以避免上述情況發生。也許我會將t,x,y保存在一個數組中,而不是數組數組,然後在稍後的階段再次分割它,在那裏我需要它們分開。 – grinsbaeckchen

+0

@grinsbaeckchen - 是否有任何理由讓't'成爲數組的一部分?它看起來有點像它只是數組的元數據。 – MSeifert

+0

是的,我需要在晚些時候't',以及相應的'x'和'y'。我需要他們在一起,而不是在一個單獨的陣列。然而,我意識到我並不需要矩陣,數組/列表就足以滿足我的需求。這使事情變得更容易一些。 我現在只使用一個列表而不是np.array。這可能會比較慢,但現在起作用。 – grinsbaeckchen

0

如果你知道你將只適用於n,m每個點存儲值t, y, x那麼它可能會更容易和更快的計算,有三個numpy的陣列。

所以:

M_T = np.zeros((n,m)) 
M_Y = np.zeros((n,m)) 
M_X = np.zeros((n,m)) 

我相信你現在可以鍵入 '正常' 的Python運營商做陣列邏輯,如:

MX = np.ones((n,m)) 
MY = np.ones((n,m)) 
MT = MX + MY 
MT ** MT 
_ * 7.5 

通過定義陣列友好的功能(類似於MATLAB)你會得到一個大大提高計算速度。

當然,如果你需要更多的變量在每個點上,那麼這可能會變得笨拙。

+0

糟糕,我意識到我沒有真正回答你的問題。 Doh – dodell