使用填充堆叠不同长度的Numpy数组

时间:2018-10-29 18:18:26

标签: python numpy

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

l = [a,b]

我想要一个函数stack_padding这样:

assert(stack_padding(l) == np.array([[1,2,3],[4,5,0]])

numpy是否有实现

的标准方法

编辑:l可能包含更多元素

3 个答案:

答案 0 :(得分:3)

我认为itertools.zip_longestfill_value=0可以为您工作:

import itertools

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

l = [a,b]

def stack_padding(l):
    return np.column_stack((itertools.zip_longest(*l, fillvalue=0)))

>>> stack_padding(l)
array([[1, 2, 3],
       [4, 5, 0]])

答案 1 :(得分:1)

使用numpy.pad

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

l = [a,b]

max_len = max([len(arr) for arr in l])
padded = np.array([np.lib.pad(arr, (0, max_len - len(arr)), 'constant', constant_values=0) for arr in l])

答案 2 :(得分:1)

如果您不想使用itertoolscolumn_stacknumpy.ndarray.resize也会做得很好。正如jtweeder所提到的,您只需要知道每行的结果大小即可。使用resize的好处是numpy.ndarray在内存中是连续的。当每一行的大小不同时,调整大小的速度更快。两种方法之间的性能差异是可以观察到的。

import numpy as np
import timeit
import itertools

def stack_padding(it):

    def resize(row, size):
        new = np.array(row)
        new.resize(size)
        return new

    # find longest row length
    row_length = max(it, key=len).__len__()
    mat = np.array( [resize(row, row_length) for row in it] )

    return mat

def stack_padding1(l):
    return np.column_stack((itertools.zip_longest(*l, fillvalue=0)))


if __name__ == "__main__":
    n_rows = 200
    row_lengths = np.random.randint(30, 50, size=n_rows)
    mat = [np.random.randint(0, 100, size=s) for s in row_lengths]

    def test_stack_padding():
        global mat
        stack_padding(mat)

    def test_itertools():
        global mat
        stack_padding1(mat)

    t1 = timeit.timeit(test_stack_padding, number=1000)
    t2 = timeit.timeit(test_itertools, number=1000)
    print('With ndarray.resize: ', t1)
    print('With itertool and vstack: ', t2)

在以上比较中,resize方法获胜:

>>> With ndarray.resize:  0.30080295499647036
>>> With itertool and vstack:  1.0151802329928614