如何使用numpy将矢量填充和/或截断到指定的长度?

时间:2015-08-19 22:38:50

标签: python numpy

我有几个列表:

a = [1,2,3]
b = [1,2,3,4,5,6]

长度可变。

我想返回长度为5的向量,这样如果输入列表长度为<然后,它将在右侧填充零,如果是> 5,然后它将被截断在第5个元素。

例如,输入a将返回np.array([1,2,3,0,0]),输入b将返回np.array([1,2,3,4,5])

我觉得我应该能够使用np.pad,但我似乎无法遵循文档。

3 个答案:

答案 0 :(得分:6)

这可能很慢或很快,我不确定,但它适用于您的目的。

In [22]: pad = lambda a,i : a[0:i] if len(a) > i else a + [0] * (i-len(a))

In [23]: pad([1,2,3], 5)
Out[23]: [1, 2, 3, 0, 0]

In [24]: pad([1,2,3,4,5,6,7], 5)
Out[24]: [1, 2, 3, 4, 5]

答案 1 :(得分:3)

np.pad有点矫枉过正,最好在2d图像周围添加边框,而不是在列表中添加一些零。

我喜欢zip_longest,特别是如果输入是列表,并且不需要是数组。它可能是您在编译代码中同时在所有列表上运行的代码中找到的最接近的。)

a, b = zip(*list(itertools.izip_longest(a, b, fillvalue=0)))

是一个完全不使用np.array的版本(节省一些数组开销)

但它本身并没有截断。它仍然像[x[:5] for x in (a,b)]

这是我对all_m函数的变体,使用简单列表或1d数组:

def foo_1d(x, n=5):
    x = np.asarray(x)
    assert x.ndim==1
    s = np.min([x.shape[0], n])
    ret = np.zeros((n,), dtype=x.dtype)
    ret[:s] = x[:s]
    return ret

In [772]: [foo_1d(x) for x in [[1,2,3], [1,2,3,4,5], np.arange(10)[::-1]]]
Out[772]: [array([1, 2, 3, 0, 0]), array([1, 2, 3, 4, 5]), array([9, 8, 7, 6, 5])]

numpy解决方案的某种方式做同样的事情 - 构造一个所需形状的空白数组,然后用原始的相关值填充它。

另一个细节 - 在理论上截断解决方案时,可以返回视图而不是副本。但是这需要将这种情况与垫盒分开处理。

如果所需的输出是相等的lenth数组的列表,那么在二维数组中收集它们可能是值得的。

In [792]: def foo1(x, out):
    x = np.asarray(x)
    s = np.min((x.shape[0], out.shape[0]))
    out[:s] = x[:s]

In [794]: lists = [[1,2,3], [1,2,3,4,5], np.arange(10)[::-1], []]

In [795]: ret=np.zeros((len(lists),5),int)
In [796]: for i,xx in enumerate(lists):
    foo1(xx, ret[i,:])
In [797]: ret
Out[797]: 
array([[1, 2, 3, 0, 0],
       [1, 2, 3, 4, 5],
       [9, 8, 7, 6, 5],
       [0, 0, 0, 0, 0]])

答案 2 :(得分:1)

纯python版本,其中a是一个python列表(不是一个numpy数组):a[:n] + [0,]*(n-len(a))

例如:

In [42]: n = 5

In [43]: a = [1, 2, 3]

In [44]: a[:n] + [0,]*(n - len(a))
Out[44]: [1, 2, 3, 0, 0]

In [45]: a = [1, 2, 3, 4]

In [46]: a[:n] + [0,]*(n - len(a))
Out[46]: [1, 2, 3, 4, 0]

In [47]: a = [1, 2, 3, 4, 5]

In [48]: a[:n] + [0,]*(n - len(a))
Out[48]: [1, 2, 3, 4, 5]

In [49]: a = [1, 2, 3, 4, 5, 6]

In [50]: a[:n] + [0,]*(n - len(a))
Out[50]: [1, 2, 3, 4, 5]

使用numpy的功能:

In [121]: def tosize(a, n):
   .....:     a = np.asarray(a)
   .....:     x = np.zeros(n, dtype=a.dtype)
   .....:     m = min(n, len(a))
   .....:     x[:m] = a[:m]
   .....:     return x
   .....: 

In [122]: tosize([1, 2, 3], 5)
Out[122]: array([1, 2, 3, 0, 0])

In [123]: tosize([1, 2, 3, 4], 5)
Out[123]: array([1, 2, 3, 4, 0])

In [124]: tosize([1, 2, 3, 4, 5], 5)
Out[124]: array([1, 2, 3, 4, 5])

In [125]: tosize([1, 2, 3, 4, 5, 6], 5)
Out[125]: array([1, 2, 3, 4, 5])