2013-08-30 97 views
2

我有一段代碼,我正在從MATLAB轉換爲python。它還沒有以非常pythonic的方式寫,但我會在稍後的階段調整它。python相當於MATLAB的代碼vec2mat

MATLAB腳本具有通信系統工具箱中的功能vec2mat。 (請參見http://www.mathworks.co.uk/help/comm/ref/vec2mat.html)通過指定要轉換的向量以及希望擁有的列數,可將矢量更改爲矩陣。 mat = vec2mat(vec,matcol)

我通常只會使用numpy.reshape。但是,如果矢量中沒有足夠的值來完全填充最後一行,vec2mat將向最後一行添加零。

我需要的填充將根據我輸入的csv文件而有所不同。

atbmat = vec2mat(atbvec,nb); 

在該示例情況下nb是5和atbvec長度爲4806因此四個零被添加到最底行。

我將如何去添加額外的零在Python中創建一個二維數組?我會有長度爲4806的一維數組atbvecnb等於五(我想要nb列)。

感謝您的任何建議,我希望這是有道理的。

編輯

 dim=len(atbvec)/int(nb) 
    atbvec=np.array(atbvec) 
    atbvec=np.copy(atbvec) 
    atb_mat=atbvec.resize((dim,nb) 

這是返回None

回答

3

可以使用一個numpy.ndarray對象的resize()方法:

import numpy as np 

a = np.array([1,2,3]) 
a.resize(2,3) 
print a 
#array([[1, 2, 3], 
#  [0, 0, 0]]) 

編輯:

注意a延伸in-place,這意味着原始陣列具有現在所涉及的參考額外的,連續的內存塊。

在你的情況的基礎上,評論,您可以事先創建一個副本:

atb_mat = atbvec.copy() 
atb_mat.resize(dim, nb) 

,或者最好,使用numpy.resize獲得不提到一個全新的數組:

atb_mat = numpy.resize(atbvec, (dim, nb)) 

但是,在這種情況下,數組填充了atbvec以前的值,例如:

a = np.array([1,2,3]) 
b = np.resize(a, (3, 4)) 
#array([[1, 2, 3, 1], 
#  [2, 3, 1, 2], 
#  [3, 1, 2, 3]]) 

看到內存塊被複制,直到它填充新的連續大小。

+0

非常感謝這麼快的回覆。這聽起來像應該起作用。 (** dim = len(atbvec)/ int(nb)) atb_mat =返回atb_mat **) –

+1

除了「resize」只是將零添加到連續的內存塊。考慮'a = np.array([[1],[2],[3]])。copy(); a.resize(3,2)'。 –

+0

@AshleighClayton這是因爲它調整''in-place'的大小,所以你的原始數組現在有一個擴展的內存塊,正如@HenryGomersall所提到的 –

1

重寫編輯:我好像誤會了這個問題,完全解決了一個問題。下面的解決方案是,如果您需要將數組展開或縮小到任意大小,則根據需要填充零。

我不知道有一個功能可以按照您的要求來操作(儘管我總是在學習!)。我能想到的最簡單的方法可能是使用numpy.pad。下面的函數,你需要什麼,只要新的造型比老形狀較大:

def vec2mat(a, new_shape): 

    padding = (new_shape - numpy.vstack((new_shape, a.shape))).T.tolist() 

    return numpy.pad(a, padding, mode='constant') 

如果您需要處理更小和更大的尺寸比原來的數組,下面應該這樣做:

def vec2mat(a, shape): 

    padding = (shape - numpy.vstack((shape, a.shape))).T 

    # Split into positive and negative padding 
    neg_padding = padding.copy() 
    neg_padding[neg_padding > 0] = 0 
    padding[padding < 0] = 0 

    # Turn the zero neg_paddings into None: 
    slice_marks = [axis if axis[1] != 0 else (None,) for axis in neg_padding] 

    # Make the slicer 
    slicer = [slice(*each_mark) for each_mark in slice_marks] 

    return numpy.pad(a[slicer], padding.tolist(), mode='constant') 

請注意,上述兩個函數都應該在任意維數組上運行。

編輯:resize作爲一個解決方案的問題是,它只展開內存中的數組,然後有效地重新塑造新的內存塊到您要求的大小。這樣做的效果是,如果您試圖沿着除了最短軸以外的任何軸進行展開,則會遇到問題。考慮沿第一軸擴展:

a = np.array([1,2,3]).copy() 
a.resize(2, 3) 
# array([[1, 2, 3], 
#  [0, 0, 0]]) 

預期其工作。然而,現在考慮沿軸線最後擴大:

a = np.array([[1],[2],[3]]).copy() 
a.resize(3, 2) 
# array([[1, 2], 
#  [3, 0], 
#  [0, 0]]) 

我不認爲這是你想要的所有東西,但請糾正我,如果我錯了。我的理解是,你需要一個數組,第一列爲[[1],[2],[3]],第二列爲全零。

+0

如果OP想要用第二列進行擴展,則只需要使用行連續的存儲器佈局,如果用a = np.array([1,2 ,3],order ='F')' –

+0

對不起,我剛剛在這裏測試過,它不工作......奇怪......它改變了內存佈局,請檢查'.flags'。 –

+0

@SaulloCastro我不認爲我的解決方案無論如何不會做什麼。它解決了另一個問題 - 特別是在所有維度上填充或縮小數組。 –