2017-02-15 35 views
1

只給你一些背景:如何翻譯Python 3中的MATLAB單元格?

我有一些MATLAB代碼轉換成Python 3的,但在這裏,我遇到了一個小問題。

Matlab的:

for i in 1:num_nodes 
    for j in 1:num_nodes 
     K{i,j} = zeros(3,3); 

其中我翻譯成:

k_topology = [[]] 
for i in range(x): 
    for i in range(x): 
     k_topology[[i][j]].extend(np.zeros(3,3)) 

而且,進一步在Matlab代碼還有第三環:

for k in 1:3 
    K{i,j}(k,k) = -1 

這也是種..讓我失望了?

事實是我真的不知道如何將這種變量轉換爲Python。另外,我猜我的Python代碼有點「破損」 - ,我沒有真的要求你們改進它 - ,所以我只是要求這是將Matlab的單元格轉換爲Python的最佳方式?根據kazemakase的答案-


我終於找到了顯然簡單把這種使用列表理解。現在的實際的Python代碼看起來像這樣:

k_topology = [[np.zeros((3,3)) for j in range(self.get_nb_nodes_from_network())]\ 
        for i in range(self.get_nb_nodes_from_network())] 

,看起來像在輸出是這樣的:

[[array([[ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.]]), 
array([[ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.]]), 
array([[ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.]])], ..., [array(...)]] 

(還有的實在太多值,它粘貼在這裏,但我覺得你得到它)

+1

它可能有助於描述那些Matlab代碼做什麼,以及爲什麼你認爲這將很難翻譯。 – Carcigenicate

+0

那麼K矩陣是爲了表示電網的拓撲結構。所以它將包含其他矩陣,長度從1到3最大。至於它,我可以理解第一個循環(帶有K {i,j}的循環),但第二個循環看起來很奇怪:什麼是K {i,j}(k,k)?我如何翻譯它?這就是爲什麼我發現它很困難:我只是不明白 – Alastard

+0

所以'K'是二維的? 'k_topology'和'K'有什麼區別? – Carcigenicate

回答

3

你需要問的第一個問題是「什麼一個Matlab單元格,什麼可能是一個合適的對應Python類型?」

如果我從我的不好的舊的Matlab天正確記得,一個單元格是一種容納混合類型內容的容器。它就像一個動態類型的數組或矩陣。它是多維索引的。

Python是動態類型的,所以任何Python contianer都可以基本完成這個功能。在Python列表被索引,所以嵌套列表可以工作 - 但它們確實有點怪異設置和訪問:

K = [[None] * num_nodes for _ in range(num_nodes)] 
K[i][j] # need two indices to access elements of a nested list. 

對於特定場景的字典更好的鏡子Matlab的語法。雖然ditionary只需要一個指標,我們可以利用元組可以不帶括號聲明的事實和字典可以採取元組爲索引:當字典是語法更簡潔

K = {} 
for i in range(num_nodes): 
    for j in range(num_nodes): 
     K[i, j] = np.zeros((3, 3)) 

     for k in 1:3 
      K[i, j][k, k] = -1 

,元素訪問是可能少高性能比在嵌套列表中。嵌套外觀與Matlab代碼不同。選擇取決於性能或與原始代碼的相似性。但是,如果表現是一個問題,無論如何還有更多的事情需要考慮。總結:沒有最好的辦法來做到這一點。


由於OP expclicitly要求不提高的代碼,我明確要求他/她的不理答案的這一部分。

構建對角矩陣的更好方法是使用np.ones而不是在對角線元素上循環。

K = {} 
for i in range(num_nodes): 
    for j in range(num_nodes): 
     K[i, j] = -np.ones((3, 3)) 

而且,嵌套表可以沒有(太多)之前初始化構造,如果這是首選的方法:

K = [] 
for i in range(num_nodes): 
    K.append([]) 
    for j in range(num_nodes): 
     K[-1].append(-np.ones((3, 3))) 

現在,我的靈魂的安寧,讓我拆開就OP的代碼提供反饋意見:

k_topology = [[]] 
for i in range(x): 
    for i in range(x): 
     k_topology[[i][j]].extend(np.zeros(3,3)) 
  1. 這有什麼做與原來Matlab代碼(不同的變量名)
  2. 兩個循環使用i。從未定義過j
  3. [[i][j]]用一個元素i建立一個列表並試圖取第j個元素。如果j是非0的東西,則會導致錯誤。
  4. list.extend a將參數的所有元素逐個追加到列表中 - 在這種情況下是單獨的行。 list.append將是正確的,因爲在整個3×3矩陣使用應K.附加爲一個元件
  5. np.zeros(3, 3)應當np.zeros((3, 3))(假設npnumpy的別名),因爲該函數採用形狀是第一個參數,而不是多個參數。
+0

那麼,謝謝你的回答,這對我來說很重要!所以我想我要檢查一個涉及嵌套列表的問題。 – Alastard

0

使用八度/ SciPy的保存/ loadmat我在鏈接後證實:

在一個八度會議

>> num_nodes=3 
num_nodes = 3 
>> num_nodes=3; 
>> K=cell(num_nodes, num_nodes); 
>> for i = 1:num_nodes 
    for j = 1:num_nodes 
     K{i,j} = zeros(2,2); 
    end 
end 

>> K 
K = 
{ 
    [1,1] = 

    0 0 
    0 0 

    [2,1] = 

    0 0 
    0 0 
etc 

訪問一個單元:

>> K{1,2} 
ans = 

    0 0 
    0 0 

訪問一個一個單元的元素:

>> K{1,2}(1,1) 
ans = 0 

>> save -7 kfile.mat K 

在Python

In [31]: from scipy import io 
In [32]: data = io.loadmat('kfile.mat') 
In [34]: data 
Out[34]: 
{'K': array([[array([[ 0., 0.], 
     [ 0., 0.]]), 
     array([[ 0., 0.], 
     [ 0., 0.]]), 
     array([[ 0., 0.], 
     [ 0., 0.]])], 
     [array([[ 0., 0.], 
     [ 0., 0.]]), 
     array([[ 0., 0.], 
     [ 0., 0.]]), 
     array([[ 0., 0.], 
     [ 0., 0.]])], 
     [array([[ 0., 0.], 
     [ 0., 0.]]), 
     array([[ 0., 0.], 
     [ 0., 0.]]), 
     array([[ 0., 0.], 
     [ 0., 0.]])]], dtype=object), 
'__globals__': [], 
'__header__': b'MATLAB 5.0 MAT-file, written by Octave 4.0.0, 2017-02-15 19:05:44 UTC', 
'__version__': '1.0'} 

In [35]: data['K'].shape 
Out[35]: (3, 3) 
In [36]: data['K'][0,0].shape 
Out[36]: (2, 2) 
In [37]: data['K'][0,0][0,0] 
Out[37]: 0.0 

loadmat對待一個cell作爲2D對象D型陣列;而常規矩陣是2d數組。對象數組在很多方面都像嵌套的Python列表。

+0

謝謝。我終於使用列表理解來解決我的問題,但我沒有使用Octave,所以我不認爲你的答案與我的問題相關 – Alastard

+0

Octave是Matlab兼容的。我正在說明Matlab結構和numpy結構之間最直接的等價關係。但直接創建2d對象數組有點尷尬,在你的情況下可能不需要。列表在python中更自然/本地化。 – hpaulj