Если вы не хотите использовать itertools
и column_stack
, numpy.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