Python等效代码到MATLABs vec2mat

时间:2013-08-30 08:51:24

标签: python arrays matlab numpy reshape

我有一段代码,我将从MATLAB转换为python。它尚未以非常pythonic的方式编写,但我将在稍后阶段进行调整。

MATLAB脚本具有来自Communications systems工具箱的函数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中添加额外的零来创建2D数组?我的长度为4806的1D数组atbvecnb等于5(我想要nb列)。

感谢您的任何建议,我希望这是有道理的。

修改

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

这将返回None

2 个答案:

答案 0 :(得分:3)

您可以使用resize()对象的numpy.ndarray方法:

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]])

看到内存块被复制,直到它填满新的连续大小。

答案 1 :(得分: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]],第二列为全零。